Implement evaluate on CfFrameState on more instructions

Bug: 214496607
Change-Id: I62312d02f1f89969b6e371dc36c0f81782517542
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
index af0b133..bf9dc6b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
@@ -225,7 +225,6 @@
       DexItemFactory dexItemFactory) {
     // ..., value1, value2 →
     // ..., result
-    FrameType frameType = FrameType.fromNumericType(type, dexItemFactory);
-    return state.pop(appView, frameType, frameType).push(frameType);
+    return state.popInitialized(appView, type).popInitialized(appView, type).push(appView, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index cdd43c2..e696048 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -100,7 +99,10 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., arrayref →
+    // ..., length
+    return frame
+        .popInitialized(appView, dexItemFactory.objectArrayType)
+        .push(dexItemFactory.intType);
   }
 }
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
index 5069f14..8cc8e63 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -145,7 +144,11 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., arrayref, index →
+    // ..., value
+    return frame
+        .popInitialized(appView, dexItemFactory.intType)
+        .popInitialized(appView, dexItemFactory.objectArrayType)
+        .push(appView, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
index c51336f..942f633 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -136,7 +135,11 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., arrayref, index, value →
+    // ...
+    return frame
+        .popInitialized(appView, type)
+        .popInitialized(appView, dexItemFactory.intType)
+        .popInitialized(appView, dexItemFactory.objectArrayType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
index 55dd90f..323a253 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -149,7 +148,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., objectref →
+    // ..., objectref
+    return frame.popInitialized(appView, dexItemFactory.objectType).push(type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
index 4ca69a0..4a42ca3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -149,7 +148,11 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., value1, value2 →
+    // ..., result
+    return frame
+        .popInitialized(appView, type)
+        .popInitialized(appView, type)
+        .push(dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index 10240e5..ff36775 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -156,7 +155,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    return frame.push(dexItemFactory.classType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
index 666da46..54c7820 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
@@ -242,7 +242,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    return frame.push(dexItemFactory.classType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
index 2f79cea..50564e3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -120,7 +119,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    return frame.push(dexItemFactory.methodHandleType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
index 0cc8d78..b262ff9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -118,7 +117,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    return frame.push(dexItemFactory.methodTypeType);
   }
 }
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
index efcd063..e849e05 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -90,7 +89,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    return frame.push(DexItemFactory.nullValueType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
index cee2f4a..34f67c7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -238,7 +237,8 @@
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    frameBuilder.push(type.toPrimitiveType().toDexType(dexItemFactory));
+    assert type.isPrimitive();
+    frameBuilder.push(type.toDexType(dexItemFactory));
   }
 
   @Override
@@ -247,7 +247,9 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    assert type.isPrimitive();
+    return frame.push(appView, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
index 5ab3742..8bccf77 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -140,7 +139,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., value
+    return frame.push(dexItemFactory.stringType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
index e7b8c99..4ab2860 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
@@ -156,7 +156,7 @@
     }
 
     public static FrameType fromNumericType(NumericType numericType, DexItemFactory factory) {
-      return FrameType.initialized(numericType.dexTypeFor(factory));
+      return FrameType.initialized(numericType.toDexType(factory));
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
index f6d94b7..dacbd9e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
@@ -156,10 +156,7 @@
       DexItemFactory dexItemFactory) {
     // ..., value1, value2 →
     // ...
-    DexType type =
-        this.type.isObject()
-            ? dexItemFactory.objectType
-            : this.type.toPrimitiveType().toDexType(dexItemFactory);
+    DexType type = this.type.toDexType(dexItemFactory);
     frameBuilder.popAndDiscardInitialized(type, type);
     frameBuilder.checkTarget(target);
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
index 4df1ecd..a168090 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -133,7 +132,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., →
+    // ..., value
+    return frame.push(dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java
index df84afd..c461c07 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.code.CfOrDexInstanceFieldRead;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -84,7 +83,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., objectref →
+    // ..., value
+    return frame.popInitialized(appView, getField().getHolderType()).push(getField().getType());
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
index da48878..53f9904 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -143,7 +142,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., objectref →
+    // ..., result
+    return frame.popInitialized(appView, dexItemFactory.objectType).push(dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index 421902e..121c288 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -187,7 +186,13 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., [arg1, [arg2 ...]] →
+    // ...
+    frame = frame.popInitialized(appView, callSite.getMethodProto().getParameters().getBacking());
+    DexType returnType = callSite.getMethodProto().getReturnType();
+    if (returnType.isVoidType()) {
+      return frame;
+    }
+    return frame.push(returnType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
index a5ee7eb..3cf6f34 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -206,7 +205,22 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., value1, value2 →
+    // ..., result
+    NumericType value1Type = type;
+    NumericType value2Type;
+    switch (opcode) {
+      case And:
+      case Or:
+      case Xor:
+        value2Type = value1Type;
+        break;
+      default:
+        value2Type = NumericType.INT;
+    }
+    return frame
+        .popInitialized(appView, value2Type)
+        .popInitialized(appView, value1Type)
+        .push(appView, value1Type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
index 85ddc69..f860f58 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -112,7 +111,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., objectref →
+    // ...
+    return frame.popInitialized(appView, dexItemFactory.objectType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
index 796a93f..a69ff20 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -149,7 +148,11 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., count1, [count2, ...] →
+    // ..., arrayref
+    for (int i = 0; i < dimensions; i++) {
+      frame = frame.popInitialized(appView, dexItemFactory.intType);
+    }
+    return frame.push(type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
index 9c6a7f8..c25b0ff 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -138,7 +137,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., value →
+    // ..., result
+    return frame.popInitialized(appView, type).push(appView, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
index ba81a58..261db2e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -173,7 +172,6 @@
       DexItemFactory dexItemFactory) {
     // ..., count →
     // ..., arrayref
-    assert type.isArrayType();
     frameBuilder.popAndDiscardInitialized(dexItemFactory.intType).push(type);
   }
 
@@ -183,7 +181,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., count →
+    // ..., arrayref
+    return frame.popInitialized(appView, dexItemFactory.intType).push(type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java b/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
index 8683ddd..73d04d1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -135,7 +134,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ... →
+    // ..., objectref
+    return frame.push(type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNop.java b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
index e8b3a2e..7bc083c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -92,7 +91,6 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    return frame;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
index 0341487..ee83adb 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -210,7 +209,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., value →
+    // ..., result
+    return frame.popInitialized(appView, from).push(appView, to);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
index 155b17d..42ebf38 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.CfCompareHelper;
@@ -125,7 +124,6 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    return frame;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java b/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
index 4a9fd91..ba04a1c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -128,7 +127,9 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    for (DexField ignored : fields) {
+      frame = frame.popInitialized(appView, dexItemFactory.objectType);
+    }
+    return frame.push(dexItemFactory.objectArrayType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
index 5f5e5a9..c929d68 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
@@ -524,8 +524,9 @@
     switch (opcode) {
       case Pop:
         {
-          // TODO(b/214496607): Implement this.
-          throw new Unimplemented();
+          // ..., value →
+          // ...
+          return frame.pop(appView, FrameType.oneWord());
         }
       case Pop2:
         {
@@ -536,7 +537,9 @@
         // ..., value →
         // ..., value, value
         return frame.pop(
-            appView, FrameType.oneWord(), frameType -> frame.push(frameType).push(frameType));
+            appView,
+            FrameType.oneWord(),
+            (newFrame, frameType) -> newFrame.push(frameType).push(frameType));
       case DupX1:
         {
           // TODO(b/214496607): Implement this.
@@ -564,8 +567,16 @@
         }
       case Swap:
         {
-          // TODO(b/214496607): Implement this.
-          throw new Unimplemented();
+          // ..., value2, value1 →
+          // ..., value1, value2
+          return frame.pop(
+              appView,
+              FrameType.oneWord(),
+              (newFrame1, frameType1) ->
+                  newFrame1.pop(
+                      appView,
+                      FrameType.oneWord(),
+                      (newFrame2, frameType2) -> newFrame2.push(frameType1).push(frameType2)));
         }
       default:
         throw new Unreachable("Invalid opcode for CfStackInstruction");
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java b/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java
index 26114d8..3c64e6a 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.cf.code;
 
-import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -83,7 +82,8 @@
       ProgramMethod context,
       AppView<?> appView,
       DexItemFactory dexItemFactory) {
-    // TODO(b/214496607): Implement this.
-    throw new Unimplemented();
+    // ..., value →
+    // ...
+    return frame.popInitialized(appView, getField().getType());
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/NumericType.java b/src/main/java/com/android/tools/r8/ir/code/NumericType.java
index 99456dc..85b80b5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NumericType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NumericType.java
@@ -16,7 +16,7 @@
   FLOAT,
   DOUBLE;
 
-  public DexType dexTypeFor(DexItemFactory factory) {
+  public DexType toDexType(DexItemFactory factory) {
     switch (this) {
       case BYTE:
         return factory.byteType;
diff --git a/src/main/java/com/android/tools/r8/ir/code/ValueType.java b/src/main/java/com/android/tools/r8/ir/code/ValueType.java
index 0ae9459..4677bd4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ValueType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ValueType.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.errors.InternalCompilerError;
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.PrimitiveTypeElement;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -38,6 +39,10 @@
     return this == OBJECT;
   }
 
+  public boolean isPrimitive() {
+    return !isObject();
+  }
+
   public boolean isSingle() {
     return this == INT || this == FLOAT;
   }
@@ -138,6 +143,23 @@
     throw new Unreachable("Unexpected conversion of imprecise type: " + type);
   }
 
+  public DexType toDexType(DexItemFactory dexItemFactory) {
+    switch (this) {
+      case OBJECT:
+        return dexItemFactory.objectType;
+      case INT:
+        return dexItemFactory.intType;
+      case FLOAT:
+        return dexItemFactory.floatType;
+      case LONG:
+        return dexItemFactory.longType;
+      case DOUBLE:
+        return dexItemFactory.doubleType;
+      default:
+        throw new Unreachable();
+    }
+  }
+
   public PrimitiveTypeElement toPrimitiveType() {
     switch (this) {
       case INT:
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
index fa902a6..734e09e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
@@ -1083,7 +1083,7 @@
             if (instruction.isInvokeMethod()) {
               argumentTypes.add(argumentTypeFromValue(value, instruction.asInvokeMethod(), i));
             } else {
-              argumentTypes.add(instruction.asBinop().getNumericType().dexTypeFor(dexItemFactory));
+              argumentTypes.add(instruction.asBinop().getNumericType().toDexType(dexItemFactory));
             }
             argumentsMap.add(argumentTypes.size() - 1);
           }
@@ -1098,7 +1098,7 @@
         } else {
           updateReturnValueState(
               instruction.outValue(),
-              instruction.asBinop().getNumericType().dexTypeFor(dexItemFactory));
+              instruction.asBinop().getNumericType().toDexType(dexItemFactory));
         }
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
index 7e0b884..3ad14fb 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
@@ -504,7 +504,7 @@
         if (temp == null) {
           return null;
         }
-        DexType conversionType = conversion.to.dexTypeFor(factory);
+        DexType conversionType = conversion.to.toDexType(factory);
         if (conversionType == factory.booleanType) {
           return temp.intValue() != 0 ? 1 : 0;
         } else if (conversionType == factory.byteType) {
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/BottomCfFrameState.java b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/BottomCfFrameState.java
index 7572341..dad22fa 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/BottomCfFrameState.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/BottomCfFrameState.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 
 public class BottomCfFrameState extends CfFrameState {
@@ -43,7 +44,9 @@
 
   @Override
   public CfFrameState pop(
-      AppView<?> appView, FrameType expectedType, Function<FrameType, CfFrameState> fn) {
+      AppView<?> appView,
+      FrameType expectedType,
+      BiFunction<CfFrameState, FrameType, CfFrameState> fn) {
     return error();
   }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfFrameState.java b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfFrameState.java
index ec899a2..01bda85 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfFrameState.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfFrameState.java
@@ -11,6 +11,10 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.framework.intraprocedural.AbstractState;
+import com.android.tools.r8.ir.code.MemberType;
+import com.android.tools.r8.ir.code.NumericType;
+import com.android.tools.r8.ir.code.ValueType;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 
 public abstract class CfFrameState extends AbstractState<CfFrameState> {
@@ -38,7 +42,9 @@
   public abstract CfFrameState pop(AppView<?> appView, FrameType expectedType);
 
   public abstract CfFrameState pop(
-      AppView<?> appView, FrameType expectedType, Function<FrameType, CfFrameState> fn);
+      AppView<?> appView,
+      FrameType expectedType,
+      BiFunction<CfFrameState, FrameType, CfFrameState> fn);
 
   public abstract CfFrameState pop(AppView<?> appView, FrameType... expectedTypes);
 
@@ -49,10 +55,34 @@
 
   public abstract CfFrameState popInitialized(AppView<?> appView, DexType... expectedTypes);
 
+  public final CfFrameState popInitialized(AppView<?> appView, MemberType memberType) {
+    return pop(appView, FrameType.fromMemberType(memberType, appView.dexItemFactory()));
+  }
+
+  public final CfFrameState popInitialized(AppView<?> appView, NumericType expectedType) {
+    return popInitialized(appView, expectedType.toDexType(appView.dexItemFactory()));
+  }
+
+  // TODO(b/214496607): Pushing a value should return an error if the stack grows larger than the
+  //  max stack height.
   public abstract CfFrameState push(DexType type);
 
+  // TODO(b/214496607): Pushing a value should return an error if the stack grows larger than the
+  //  max stack height.
   public abstract CfFrameState push(FrameType frameType);
 
+  public final CfFrameState push(AppView<?> appView, MemberType memberType) {
+    return push(FrameType.fromMemberType(memberType, appView.dexItemFactory()));
+  }
+
+  public final CfFrameState push(AppView<?> appView, NumericType numericType) {
+    return push(numericType.toDexType(appView.dexItemFactory()));
+  }
+
+  public final CfFrameState push(AppView<?> appView, ValueType valueType) {
+    return push(valueType.toDexType(appView.dexItemFactory()));
+  }
+
   @Override
   public final CfFrameState join(CfFrameState state) {
     // TODO(b/214496607): Implement join.
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ConcreteCfFrameState.java b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ConcreteCfFrameState.java
index 63654b3..4abdc0f 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ConcreteCfFrameState.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ConcreteCfFrameState.java
@@ -18,6 +18,7 @@
 import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.Objects;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 
 public class ConcreteCfFrameState extends CfFrameState {
@@ -76,16 +77,18 @@
 
   @Override
   public CfFrameState pop(AppView<?> appView, FrameType expectedType) {
-    return pop(appView, expectedType, ignore -> this);
+    return pop(appView, expectedType, (newFrame, ignore) -> newFrame);
   }
 
   @Override
   public CfFrameState pop(
-      AppView<?> appView, FrameType expectedType, Function<FrameType, CfFrameState> fn) {
+      AppView<?> appView,
+      FrameType expectedType,
+      BiFunction<CfFrameState, FrameType, CfFrameState> fn) {
     return pop(
         frameType ->
             CfAssignability.isAssignable(frameType, expectedType, appView)
-                ? fn.apply(frameType)
+                ? fn.apply(this, frameType)
                 : error());
   }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ErroneousCfFrameState.java b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ErroneousCfFrameState.java
index 7e71f93..cdbeba2 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ErroneousCfFrameState.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/ErroneousCfFrameState.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 
 /** An analysis state representing that the code does not type check. */
@@ -44,7 +45,9 @@
 
   @Override
   public CfFrameState pop(
-      AppView<?> appView, FrameType expectedType, Function<FrameType, CfFrameState> fn) {
+      AppView<?> appView,
+      FrameType expectedType,
+      BiFunction<CfFrameState, FrameType, CfFrameState> fn) {
     return this;
   }