Fix monitor stack depth bug, allow unresolved field in put.

Change-Id: I9625fc24c49e4d8e453ff545c50b0c64c0f1ae3b
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 5ab21bb..3ad9996 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -766,7 +766,7 @@
     verifier_->Fail(VERIFY_ERROR_GENERIC) << "monitor-enter on non-object (" << reg_type << ")";
   } else {
     SetRegToLockDepth(reg_idx, monitors_.size());
-    monitors_.push(insn_idx);
+    monitors_.push_back(insn_idx);
   }
 }
 
@@ -777,7 +777,7 @@
   } else if (monitors_.empty()) {
     verifier_->Fail(VERIFY_ERROR_GENERIC) << "monitor-exit stack underflow";
   } else {
-    monitors_.pop();
+    monitors_.pop_back();
     if(!IsSetLockDepth(reg_idx, monitors_.size())) {
       // Bug 3215458: Locks and unlocks are on objects, if that object is a literal then before
       // format "036" the constant collector may create unlocks on the same object but referenced
@@ -812,7 +812,7 @@
       line_[idx] = new_type.GetId();
     }
   }
-  if(monitors_ != incoming_line->monitors_) {
+  if(monitors_.size() != incoming_line->monitors_.size()) {
     verifier_->Fail(VERIFY_ERROR_GENERIC) << "mismatched stack depths (depth="
         << MonitorStackDepth() << ", incoming depth=" << incoming_line->MonitorStackDepth() << ")";
   } else if (reg_to_lock_depths_ != incoming_line->reg_to_lock_depths_) {
@@ -3407,22 +3407,35 @@
 
 void DexVerifier::VerifyISPut(const Instruction::DecodedInstruction& dec_insn,
                               const RegType& insn_type, bool is_primitive, bool is_static) {
+  uint32_t field_idx = is_static ? dec_insn.vB_ : dec_insn.vC_;
   Field* field;
   if (is_static) {
-    field = GetStaticField(dec_insn.vB_);
+    field = GetStaticField(field_idx);
   } else {
     const RegType& object_type = work_line_->GetRegisterType(dec_insn.vB_);
-    field = GetInstanceField(object_type, dec_insn.vC_);
+    field = GetInstanceField(object_type, field_idx);
   }
-  if (field != NULL) {
-    if (field->IsFinal() && field->GetDeclaringClass() != method_->GetDeclaringClass()) {
-      Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
-                               << " from other class " << PrettyClass(method_->GetDeclaringClass());
-      return;
+  if (failure_ != VERIFY_ERROR_NONE) {
+    work_line_->SetRegisterType(dec_insn.vA_, reg_types_.Unknown());
+  } else {
+    const char* descriptor;
+    const ClassLoader* loader;
+    if (field != NULL) {
+      descriptor = field->GetTypeDescriptor();
+      loader = field->GetDeclaringClass()->GetClassLoader();
+    } else {
+      const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
+      descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
+      loader = method_->GetDeclaringClass()->GetClassLoader();
     }
-    const RegType& field_type =
-        reg_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
-                                  field->GetTypeDescriptor());
+    const RegType& field_type = reg_types_.FromDescriptor(loader, descriptor);
+    if (field != NULL) {
+      if (field->IsFinal() && field->GetDeclaringClass() != method_->GetDeclaringClass()) {
+        Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
+                               << " from other class " << PrettyClass(method_->GetDeclaringClass());
+        return;
+      }
+    }
     if (is_primitive) {
       // Primitive field assignability rules are weaker than regular assignability rules
       bool instruction_compatible;