Merge new array with new array filled logic

Change-Id: Ia6ade5651e96d3bfcbfa208b354b2dac47f9e040
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 2fb6492..3e5ebd7 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -2159,43 +2159,17 @@
       }
       break;
     }
-    case Instruction::NEW_ARRAY: {
-      const RegType& res_type = ResolveClassAndCheckAccess(dec_insn.vC_);
-      if (res_type.IsUnknown()) {
-        CHECK_NE(failure_, VERIFY_ERROR_NONE);
-      } else {
-        // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
-        if (!res_type.IsArrayTypes()) {
-          Fail(VERIFY_ERROR_GENERIC) << "new-array on non-array class " << res_type;
-        } else {
-          /* make sure "size" register is valid type */
-          work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Integer());
-          /* set register type to array class */
-          work_line_->SetRegisterType(dec_insn.vA_, res_type);
-        }
-      }
+    case Instruction::NEW_ARRAY:
+      VerifyNewArray(dec_insn, false, false);
       break;
-    }
     case Instruction::FILLED_NEW_ARRAY:
-    case Instruction::FILLED_NEW_ARRAY_RANGE: {
-      const RegType& res_type = ResolveClassAndCheckAccess(dec_insn.vB_);
-      if (res_type.IsUnknown()) {
-        CHECK_NE(failure_, VERIFY_ERROR_NONE);
-      } else {
-        // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
-        if (!res_type.IsArrayTypes()) {
-          Fail(VERIFY_ERROR_GENERIC) << "filled-new-array on non-array class";
-        } else {
-          bool is_range = (dec_insn.opcode_ == Instruction::FILLED_NEW_ARRAY_RANGE);
-          /* check the arguments to the instruction */
-          VerifyFilledNewArrayRegs(dec_insn, res_type, is_range);
-          /* filled-array result goes into "result" register */
-          work_line_->SetResultRegisterType(res_type);
-          just_set_result = true;
-        }
-      }
+      VerifyNewArray(dec_insn, true, false);
+      just_set_result = true;  // Filled new array sets result register
       break;
-    }
+    case Instruction::FILLED_NEW_ARRAY_RANGE:
+      VerifyNewArray(dec_insn, true, true);
+      just_set_result = true;  // Filled new array range sets result register
+      break;
     case Instruction::CMPL_FLOAT:
     case Instruction::CMPG_FLOAT:
       if (!work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Float())) {
@@ -3315,6 +3289,39 @@
                                    MethodHelper(method_).GetReturnTypeDescriptor());
 }
 
+void DexVerifier::VerifyNewArray(const Instruction::DecodedInstruction& dec_insn, bool is_filled,
+                                 bool is_range) {
+  const RegType& res_type = ResolveClassAndCheckAccess(is_filled ? dec_insn.vB_ : dec_insn.vC_);
+  if (res_type.IsUnknown()) {
+    CHECK_NE(failure_, VERIFY_ERROR_NONE);
+  } else {
+    // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
+    if (!res_type.IsArrayTypes()) {
+      Fail(VERIFY_ERROR_GENERIC) << "new-array on non-array class " << res_type;
+    } else if (!is_filled) {
+      /* make sure "size" register is valid type */
+      work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Integer());
+      /* set register type to array class */
+      work_line_->SetRegisterType(dec_insn.vA_, res_type);
+    } else {
+      // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
+      // the list and fail. It's legal, if silly, for arg_count to be zero.
+      const RegType& expected_type = reg_types_.GetComponentType(res_type,
+                                                    method_->GetDeclaringClass()->GetClassLoader());
+      uint32_t arg_count = dec_insn.vA_;
+      for (size_t ui = 0; ui < arg_count; ui++) {
+        uint32_t get_reg = is_range ? dec_insn.vC_ + ui : dec_insn.arg_[ui];
+        if (!work_line_->VerifyRegisterType(get_reg, expected_type)) {
+          work_line_->SetResultRegisterType(reg_types_.Unknown());
+          return;
+        }
+      }
+      // filled-array result goes into "result" register
+      work_line_->SetResultRegisterType(res_type);
+    }
+  }
+}
+
 void DexVerifier::VerifyAGet(const Instruction::DecodedInstruction& dec_insn,
                              const RegType& insn_type, bool is_primitive) {
   const RegType& index_type = work_line_->GetRegisterType(dec_insn.vC_);
@@ -3626,30 +3633,6 @@
   return true;
 }
 
-void DexVerifier::VerifyFilledNewArrayRegs(const Instruction::DecodedInstruction& dec_insn,
-                                           const RegType& res_type, bool is_range) {
-  DCHECK(res_type.IsArrayTypes()) << res_type;  // Checked before calling.
-  /*
-   * Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of the
-   * list and fail. It's legal, if silly, for arg_count to be zero.
-   */
-  const RegType& expected_type = reg_types_.GetComponentType(res_type,
-                                                   method_->GetDeclaringClass()->GetClassLoader());
-  uint32_t arg_count = dec_insn.vA_;
-  for (size_t ui = 0; ui < arg_count; ui++) {
-    uint32_t get_reg;
-
-    if (is_range)
-      get_reg = dec_insn.vC_ + ui;
-    else
-      get_reg = dec_insn.arg_[ui];
-
-    if (!work_line_->VerifyRegisterType(get_reg, expected_type)) {
-      return;
-    }
-  }
-}
-
 void DexVerifier::ReplaceFailingInstruction() {
   if (Runtime::Current()->IsStarted()) {
     LOG(ERROR) << "Verification attempting to replacing instructions in " << PrettyMethod(method_)