Home | History | Annotate | Download | only in verifier
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "method_verifier-inl.h"
     18 
     19 #include <iostream>
     20 
     21 #include "android-base/stringprintf.h"
     22 
     23 #include "art_field-inl.h"
     24 #include "art_method-inl.h"
     25 #include "base/aborting.h"
     26 #include "base/enums.h"
     27 #include "base/leb128.h"
     28 #include "base/logging.h"  // For VLOG.
     29 #include "base/mutex-inl.h"
     30 #include "base/stl_util.h"
     31 #include "base/systrace.h"
     32 #include "base/time_utils.h"
     33 #include "base/utils.h"
     34 #include "class_linker.h"
     35 #include "compiler_callbacks.h"
     36 #include "dex/descriptors_names.h"
     37 #include "dex/dex_file-inl.h"
     38 #include "dex/dex_file_exception_helpers.h"
     39 #include "dex/dex_instruction-inl.h"
     40 #include "dex/dex_instruction_utils.h"
     41 #include "experimental_flags.h"
     42 #include "gc/accounting/card_table-inl.h"
     43 #include "handle_scope-inl.h"
     44 #include "indenter.h"
     45 #include "intern_table.h"
     46 #include "mirror/class-inl.h"
     47 #include "mirror/class.h"
     48 #include "mirror/dex_cache-inl.h"
     49 #include "mirror/method_handle_impl.h"
     50 #include "mirror/method_type.h"
     51 #include "mirror/object-inl.h"
     52 #include "mirror/object_array-inl.h"
     53 #include "mirror/var_handle.h"
     54 #include "reg_type-inl.h"
     55 #include "register_line-inl.h"
     56 #include "runtime.h"
     57 #include "scoped_thread_state_change-inl.h"
     58 #include "stack.h"
     59 #include "vdex_file.h"
     60 #include "verifier_compiler_binding.h"
     61 #include "verifier_deps.h"
     62 
     63 namespace art {
     64 namespace verifier {
     65 
     66 using android::base::StringPrintf;
     67 
     68 static constexpr bool kTimeVerifyMethod = !kIsDebugBuild;
     69 
     70 // On VLOG(verifier), should we dump the whole state when we run into a hard failure?
     71 static constexpr bool kDumpRegLinesOnHardFailureIfVLOG = true;
     72 
     73 // We print a warning blurb about "dx --no-optimize" when we find monitor-locking issues. Make
     74 // sure we only print this once.
     75 static bool gPrintedDxMonitorText = false;
     76 
     77 PcToRegisterLineTable::PcToRegisterLineTable(ScopedArenaAllocator& allocator)
     78     : register_lines_(allocator.Adapter(kArenaAllocVerifier)) {}
     79 
     80 void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* flags,
     81                                  uint32_t insns_size, uint16_t registers_size,
     82                                  MethodVerifier* verifier) {
     83   DCHECK_GT(insns_size, 0U);
     84   register_lines_.resize(insns_size);
     85   for (uint32_t i = 0; i < insns_size; i++) {
     86     bool interesting = false;
     87     switch (mode) {
     88       case kTrackRegsAll:
     89         interesting = flags[i].IsOpcode();
     90         break;
     91       case kTrackCompilerInterestPoints:
     92         interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget();
     93         break;
     94       case kTrackRegsBranches:
     95         interesting = flags[i].IsBranchTarget();
     96         break;
     97       default:
     98         break;
     99     }
    100     if (interesting) {
    101       register_lines_[i].reset(RegisterLine::Create(registers_size, verifier));
    102     }
    103   }
    104 }
    105 
    106 PcToRegisterLineTable::~PcToRegisterLineTable() {}
    107 
    108 // Note: returns true on failure.
    109 inline bool MethodVerifier::FailOrAbort(bool condition,
    110                                         const char* error_msg,
    111                                         uint32_t work_insn_idx) {
    112   if (kIsDebugBuild) {
    113     // In a debug build, abort if the error condition is wrong. Only warn if
    114     // we are already aborting (as this verification is likely run to print
    115     // lock information).
    116     if (LIKELY(gAborting == 0)) {
    117       DCHECK(condition) << error_msg << work_insn_idx << " "
    118                         << dex_file_->PrettyMethod(dex_method_idx_);
    119     } else {
    120       if (!condition) {
    121         LOG(ERROR) << error_msg << work_insn_idx;
    122         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
    123         return true;
    124       }
    125     }
    126   } else {
    127     // In a non-debug build, just fail the class.
    128     if (!condition) {
    129       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
    130       return true;
    131     }
    132   }
    133 
    134   return false;
    135 }
    136 
    137 static void SafelyMarkAllRegistersAsConflicts(MethodVerifier* verifier, RegisterLine* reg_line) {
    138   if (verifier->IsInstanceConstructor()) {
    139     // Before we mark all regs as conflicts, check that we don't have an uninitialized this.
    140     reg_line->CheckConstructorReturn(verifier);
    141   }
    142   reg_line->MarkAllRegistersAsConflicts(verifier);
    143 }
    144 
    145 FailureKind MethodVerifier::VerifyClass(Thread* self,
    146                                         mirror::Class* klass,
    147                                         CompilerCallbacks* callbacks,
    148                                         bool allow_soft_failures,
    149                                         HardFailLogMode log_level,
    150                                         std::string* error) {
    151   if (klass->IsVerified()) {
    152     return FailureKind::kNoFailure;
    153   }
    154   bool early_failure = false;
    155   std::string failure_message;
    156   const DexFile& dex_file = klass->GetDexFile();
    157   const DexFile::ClassDef* class_def = klass->GetClassDef();
    158   mirror::Class* super = klass->GetSuperClass();
    159   std::string temp;
    160   if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) {
    161     early_failure = true;
    162     failure_message = " that has no super class";
    163   } else if (super != nullptr && super->IsFinal()) {
    164     early_failure = true;
    165     failure_message = " that attempts to sub-class final class " + super->PrettyDescriptor();
    166   } else if (class_def == nullptr) {
    167     early_failure = true;
    168     failure_message = " that isn't present in dex file " + dex_file.GetLocation();
    169   }
    170   if (early_failure) {
    171     *error = "Verifier rejected class " + klass->PrettyDescriptor() + failure_message;
    172     if (callbacks != nullptr) {
    173       ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
    174       callbacks->ClassRejected(ref);
    175     }
    176     return FailureKind::kHardFailure;
    177   }
    178   StackHandleScope<2> hs(self);
    179   Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
    180   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
    181   return VerifyClass(self,
    182                      &dex_file,
    183                      dex_cache,
    184                      class_loader,
    185                      *class_def,
    186                      callbacks,
    187                      allow_soft_failures,
    188                      log_level,
    189                      error);
    190 }
    191 
    192 template <bool kDirect>
    193 static bool HasNextMethod(ClassDataItemIterator* it) {
    194   return kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod();
    195 }
    196 
    197 static FailureKind FailureKindMax(FailureKind fk1, FailureKind fk2) {
    198   static_assert(FailureKind::kNoFailure < FailureKind::kSoftFailure
    199                     && FailureKind::kSoftFailure < FailureKind::kHardFailure,
    200                 "Unexpected FailureKind order");
    201   return std::max(fk1, fk2);
    202 }
    203 
    204 void MethodVerifier::FailureData::Merge(const MethodVerifier::FailureData& fd) {
    205   kind = FailureKindMax(kind, fd.kind);
    206   types |= fd.types;
    207 }
    208 
    209 template <bool kDirect>
    210 MethodVerifier::FailureData MethodVerifier::VerifyMethods(Thread* self,
    211                                                           ClassLinker* linker,
    212                                                           const DexFile* dex_file,
    213                                                           const DexFile::ClassDef& class_def,
    214                                                           ClassDataItemIterator* it,
    215                                                           Handle<mirror::DexCache> dex_cache,
    216                                                           Handle<mirror::ClassLoader> class_loader,
    217                                                           CompilerCallbacks* callbacks,
    218                                                           bool allow_soft_failures,
    219                                                           HardFailLogMode log_level,
    220                                                           bool need_precise_constants,
    221                                                           std::string* error_string) {
    222   DCHECK(it != nullptr);
    223 
    224   MethodVerifier::FailureData failure_data;
    225 
    226   int64_t previous_method_idx = -1;
    227   while (HasNextMethod<kDirect>(it)) {
    228     self->AllowThreadSuspension();
    229     uint32_t method_idx = it->GetMemberIndex();
    230     if (method_idx == previous_method_idx) {
    231       // smali can create dex files with two encoded_methods sharing the same method_idx
    232       // http://code.google.com/p/smali/issues/detail?id=119
    233       it->Next();
    234       continue;
    235     }
    236     previous_method_idx = method_idx;
    237     InvokeType type = it->GetMethodInvokeType(class_def);
    238     ArtMethod* method = linker->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
    239         method_idx, dex_cache, class_loader, /* referrer */ nullptr, type);
    240     if (method == nullptr) {
    241       DCHECK(self->IsExceptionPending());
    242       // We couldn't resolve the method, but continue regardless.
    243       self->ClearException();
    244     } else {
    245       DCHECK(method->GetDeclaringClassUnchecked() != nullptr) << type;
    246     }
    247     StackHandleScope<1> hs(self);
    248     std::string hard_failure_msg;
    249     MethodVerifier::FailureData result = VerifyMethod(self,
    250                                                       method_idx,
    251                                                       dex_file,
    252                                                       dex_cache,
    253                                                       class_loader,
    254                                                       class_def,
    255                                                       it->GetMethodCodeItem(),
    256                                                       method,
    257                                                       it->GetMethodAccessFlags(),
    258                                                       callbacks,
    259                                                       allow_soft_failures,
    260                                                       log_level,
    261                                                       need_precise_constants,
    262                                                       &hard_failure_msg);
    263     if (result.kind == FailureKind::kHardFailure) {
    264       if (failure_data.kind == FailureKind::kHardFailure) {
    265         // If we logged an error before, we need a newline.
    266         *error_string += "\n";
    267       } else {
    268         // If we didn't log a hard failure before, print the header of the message.
    269         *error_string += "Verifier rejected class ";
    270         *error_string += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
    271         *error_string += ":";
    272       }
    273       *error_string += " ";
    274       *error_string += hard_failure_msg;
    275     }
    276     failure_data.Merge(result);
    277     it->Next();
    278   }
    279 
    280   return failure_data;
    281 }
    282 
    283 FailureKind MethodVerifier::VerifyClass(Thread* self,
    284                                         const DexFile* dex_file,
    285                                         Handle<mirror::DexCache> dex_cache,
    286                                         Handle<mirror::ClassLoader> class_loader,
    287                                         const DexFile::ClassDef& class_def,
    288                                         CompilerCallbacks* callbacks,
    289                                         bool allow_soft_failures,
    290                                         HardFailLogMode log_level,
    291                                         std::string* error) {
    292   SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
    293 
    294   // A class must not be abstract and final.
    295   if ((class_def.access_flags_ & (kAccAbstract | kAccFinal)) == (kAccAbstract | kAccFinal)) {
    296     *error = "Verifier rejected class ";
    297     *error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
    298     *error += ": class is abstract and final.";
    299     return FailureKind::kHardFailure;
    300   }
    301 
    302   const uint8_t* class_data = dex_file->GetClassData(class_def);
    303   if (class_data == nullptr) {
    304     // empty class, probably a marker interface
    305     return FailureKind::kNoFailure;
    306   }
    307   ClassDataItemIterator it(*dex_file, class_data);
    308   it.SkipAllFields();
    309   ClassLinker* linker = Runtime::Current()->GetClassLinker();
    310   // Direct methods.
    311   MethodVerifier::FailureData data1 = VerifyMethods<true>(self,
    312                                                           linker,
    313                                                           dex_file,
    314                                                           class_def,
    315                                                           &it,
    316                                                           dex_cache,
    317                                                           class_loader,
    318                                                           callbacks,
    319                                                           allow_soft_failures,
    320                                                           log_level,
    321                                                           false /* need precise constants */,
    322                                                           error);
    323   // Virtual methods.
    324   MethodVerifier::FailureData data2 = VerifyMethods<false>(self,
    325                                                            linker,
    326                                                            dex_file,
    327                                                            class_def,
    328                                                            &it,
    329                                                            dex_cache,
    330                                                            class_loader,
    331                                                            callbacks,
    332                                                            allow_soft_failures,
    333                                                            log_level,
    334                                                            false /* need precise constants */,
    335                                                            error);
    336 
    337   data1.Merge(data2);
    338 
    339   if (data1.kind == FailureKind::kNoFailure) {
    340     return FailureKind::kNoFailure;
    341   } else {
    342     if ((data1.types & VERIFY_ERROR_LOCKING) != 0) {
    343       // Print a warning about expected slow-down. Use a string temporary to print one contiguous
    344       // warning.
    345       std::string tmp =
    346           StringPrintf("Class %s failed lock verification and will run slower.",
    347                        PrettyDescriptor(dex_file->GetClassDescriptor(class_def)).c_str());
    348       if (!gPrintedDxMonitorText) {
    349         tmp = tmp + "\nCommon causes for lock verification issues are non-optimized dex code\n"
    350                     "and incorrect proguard optimizations.";
    351         gPrintedDxMonitorText = true;
    352       }
    353       LOG(WARNING) << tmp;
    354     }
    355     return data1.kind;
    356   }
    357 }
    358 
    359 static bool IsLargeMethod(const CodeItemDataAccessor& accessor) {
    360   if (!accessor.HasCodeItem()) {
    361     return false;
    362   }
    363 
    364   uint16_t registers_size = accessor.RegistersSize();
    365   uint32_t insns_size = accessor.InsnsSizeInCodeUnits();
    366 
    367   return registers_size * insns_size > 4*1024*1024;
    368 }
    369 
    370 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
    371                                                          uint32_t method_idx,
    372                                                          const DexFile* dex_file,
    373                                                          Handle<mirror::DexCache> dex_cache,
    374                                                          Handle<mirror::ClassLoader> class_loader,
    375                                                          const DexFile::ClassDef& class_def,
    376                                                          const DexFile::CodeItem* code_item,
    377                                                          ArtMethod* method,
    378                                                          uint32_t method_access_flags,
    379                                                          CompilerCallbacks* callbacks,
    380                                                          bool allow_soft_failures,
    381                                                          HardFailLogMode log_level,
    382                                                          bool need_precise_constants,
    383                                                          std::string* hard_failure_msg) {
    384   MethodVerifier::FailureData result;
    385   uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0;
    386 
    387   MethodVerifier verifier(self,
    388                           dex_file,
    389                           dex_cache,
    390                           class_loader,
    391                           class_def,
    392                           code_item,
    393                           method_idx,
    394                           method,
    395                           method_access_flags,
    396                           true /* can_load_classes */,
    397                           allow_soft_failures,
    398                           need_precise_constants,
    399                           false /* verify to dump */,
    400                           true /* allow_thread_suspension */);
    401   if (verifier.Verify()) {
    402     // Verification completed, however failures may be pending that didn't cause the verification
    403     // to hard fail.
    404     CHECK(!verifier.have_pending_hard_failure_);
    405 
    406     if (code_item != nullptr && callbacks != nullptr) {
    407       // Let the interested party know that the method was verified.
    408       callbacks->MethodVerified(&verifier);
    409     }
    410 
    411     if (verifier.failures_.size() != 0) {
    412       if (VLOG_IS_ON(verifier)) {
    413         verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in "
    414                                                     << dex_file->PrettyMethod(method_idx) << "\n");
    415       }
    416       if (VLOG_IS_ON(verifier_debug)) {
    417         std::cout << "\n" << verifier.info_messages_.str();
    418         verifier.Dump(std::cout);
    419       }
    420       result.kind = FailureKind::kSoftFailure;
    421       if (method != nullptr &&
    422           !CanCompilerHandleVerificationFailure(verifier.encountered_failure_types_)) {
    423         method->SetDontCompile();
    424       }
    425     }
    426     if (method != nullptr) {
    427       if (verifier.HasInstructionThatWillThrow()) {
    428         method->SetDontCompile();
    429         if (Runtime::Current()->IsAotCompiler() &&
    430             (callbacks != nullptr) && !callbacks->IsBootImage()) {
    431           // When compiling apps, make HasInstructionThatWillThrow a soft error to trigger
    432           // re-verification at runtime.
    433           // The dead code after the throw is not verified and might be invalid. This may cause
    434           // the JIT compiler to crash since it assumes that all the code is valid.
    435           //
    436           // There's a strong assumption that the entire boot image is verified and all its dex
    437           // code is valid (even the dead and unverified one). As such this is done only for apps.
    438           // (CompilerDriver DCHECKs in VerifyClassVisitor that methods from boot image are
    439           // fully verified).
    440           result.kind = FailureKind::kSoftFailure;
    441         }
    442       }
    443       if ((verifier.encountered_failure_types_ & VerifyError::VERIFY_ERROR_LOCKING) != 0) {
    444         method->SetMustCountLocks();
    445       }
    446     }
    447   } else {
    448     // Bad method data.
    449     CHECK_NE(verifier.failures_.size(), 0U);
    450 
    451     if (UNLIKELY(verifier.have_pending_experimental_failure_)) {
    452       // Failed due to being forced into interpreter. This is ok because
    453       // we just want to skip verification.
    454       result.kind = FailureKind::kSoftFailure;
    455     } else {
    456       CHECK(verifier.have_pending_hard_failure_);
    457       if (VLOG_IS_ON(verifier)) {
    458         log_level = std::max(HardFailLogMode::kLogVerbose, log_level);
    459       }
    460       if (log_level >= HardFailLogMode::kLogVerbose) {
    461         LogSeverity severity;
    462         switch (log_level) {
    463           case HardFailLogMode::kLogVerbose:
    464             severity = LogSeverity::VERBOSE;
    465             break;
    466           case HardFailLogMode::kLogWarning:
    467             severity = LogSeverity::WARNING;
    468             break;
    469           case HardFailLogMode::kLogInternalFatal:
    470             severity = LogSeverity::FATAL_WITHOUT_ABORT;
    471             break;
    472           default:
    473             LOG(FATAL) << "Unsupported log-level " << static_cast<uint32_t>(log_level);
    474             UNREACHABLE();
    475         }
    476         verifier.DumpFailures(LOG_STREAM(severity) << "Verification error in "
    477                                                    << dex_file->PrettyMethod(method_idx)
    478                                                    << "\n");
    479       }
    480       if (hard_failure_msg != nullptr) {
    481         CHECK(!verifier.failure_messages_.empty());
    482         *hard_failure_msg =
    483             verifier.failure_messages_[verifier.failure_messages_.size() - 1]->str();
    484       }
    485       result.kind = FailureKind::kHardFailure;
    486 
    487       if (callbacks != nullptr) {
    488         // Let the interested party know that we failed the class.
    489         ClassReference ref(dex_file, dex_file->GetIndexForClassDef(class_def));
    490         callbacks->ClassRejected(ref);
    491       }
    492     }
    493     if (VLOG_IS_ON(verifier) || VLOG_IS_ON(verifier_debug)) {
    494       std::cout << "\n" << verifier.info_messages_.str();
    495       verifier.Dump(std::cout);
    496     }
    497   }
    498   if (kTimeVerifyMethod) {
    499     uint64_t duration_ns = NanoTime() - start_ns;
    500     if (duration_ns > MsToNs(100)) {
    501       LOG(WARNING) << "Verification of " << dex_file->PrettyMethod(method_idx)
    502                    << " took " << PrettyDuration(duration_ns)
    503                    << (IsLargeMethod(verifier.CodeItem()) ? " (large method)" : "");
    504     }
    505   }
    506   result.types = verifier.encountered_failure_types_;
    507   return result;
    508 }
    509 
    510 MethodVerifier* MethodVerifier::VerifyMethodAndDump(Thread* self,
    511                                                     VariableIndentationOutputStream* vios,
    512                                                     uint32_t dex_method_idx,
    513                                                     const DexFile* dex_file,
    514                                                     Handle<mirror::DexCache> dex_cache,
    515                                                     Handle<mirror::ClassLoader> class_loader,
    516                                                     const DexFile::ClassDef& class_def,
    517                                                     const DexFile::CodeItem* code_item,
    518                                                     ArtMethod* method,
    519                                                     uint32_t method_access_flags) {
    520   MethodVerifier* verifier = new MethodVerifier(self,
    521                                                 dex_file,
    522                                                 dex_cache,
    523                                                 class_loader,
    524                                                 class_def,
    525                                                 code_item,
    526                                                 dex_method_idx,
    527                                                 method,
    528                                                 method_access_flags,
    529                                                 true /* can_load_classes */,
    530                                                 true /* allow_soft_failures */,
    531                                                 true /* need_precise_constants */,
    532                                                 true /* verify_to_dump */,
    533                                                 true /* allow_thread_suspension */);
    534   verifier->Verify();
    535   verifier->DumpFailures(vios->Stream());
    536   vios->Stream() << verifier->info_messages_.str();
    537   // Only dump and return if no hard failures. Otherwise the verifier may be not fully initialized
    538   // and querying any info is dangerous/can abort.
    539   if (verifier->have_pending_hard_failure_) {
    540     delete verifier;
    541     return nullptr;
    542   } else {
    543     verifier->Dump(vios);
    544     return verifier;
    545   }
    546 }
    547 
    548 MethodVerifier::MethodVerifier(Thread* self,
    549                                const DexFile* dex_file,
    550                                Handle<mirror::DexCache> dex_cache,
    551                                Handle<mirror::ClassLoader> class_loader,
    552                                const DexFile::ClassDef& class_def,
    553                                const DexFile::CodeItem* code_item,
    554                                uint32_t dex_method_idx,
    555                                ArtMethod* method,
    556                                uint32_t method_access_flags,
    557                                bool can_load_classes,
    558                                bool allow_soft_failures,
    559                                bool need_precise_constants,
    560                                bool verify_to_dump,
    561                                bool allow_thread_suspension)
    562     : self_(self),
    563       arena_stack_(Runtime::Current()->GetArenaPool()),
    564       allocator_(&arena_stack_),
    565       reg_types_(can_load_classes, allocator_, allow_thread_suspension),
    566       reg_table_(allocator_),
    567       work_insn_idx_(dex::kDexNoIndex),
    568       dex_method_idx_(dex_method_idx),
    569       method_being_verified_(method),
    570       method_access_flags_(method_access_flags),
    571       return_type_(nullptr),
    572       dex_file_(dex_file),
    573       dex_cache_(dex_cache),
    574       class_loader_(class_loader),
    575       class_def_(class_def),
    576       code_item_accessor_(*dex_file, code_item),
    577       declaring_class_(nullptr),
    578       interesting_dex_pc_(-1),
    579       monitor_enter_dex_pcs_(nullptr),
    580       have_pending_hard_failure_(false),
    581       have_pending_runtime_throw_failure_(false),
    582       have_pending_experimental_failure_(false),
    583       have_any_pending_runtime_throw_failure_(false),
    584       new_instance_count_(0),
    585       monitor_enter_count_(0),
    586       encountered_failure_types_(0),
    587       can_load_classes_(can_load_classes),
    588       allow_soft_failures_(allow_soft_failures),
    589       need_precise_constants_(need_precise_constants),
    590       has_check_casts_(false),
    591       has_virtual_or_interface_invokes_(false),
    592       verify_to_dump_(verify_to_dump),
    593       allow_thread_suspension_(allow_thread_suspension),
    594       is_constructor_(false),
    595       link_(nullptr) {
    596   self->PushVerifier(this);
    597 }
    598 
    599 MethodVerifier::~MethodVerifier() {
    600   Thread::Current()->PopVerifier(this);
    601   STLDeleteElements(&failure_messages_);
    602 }
    603 
    604 void MethodVerifier::FindLocksAtDexPc(
    605     ArtMethod* m,
    606     uint32_t dex_pc,
    607     std::vector<MethodVerifier::DexLockInfo>* monitor_enter_dex_pcs) {
    608   StackHandleScope<2> hs(Thread::Current());
    609   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    610   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    611   MethodVerifier verifier(hs.Self(),
    612                           m->GetDexFile(),
    613                           dex_cache,
    614                           class_loader,
    615                           m->GetClassDef(),
    616                           m->GetCodeItem(),
    617                           m->GetDexMethodIndex(),
    618                           m,
    619                           m->GetAccessFlags(),
    620                           false /* can_load_classes */,
    621                           true  /* allow_soft_failures */,
    622                           false /* need_precise_constants */,
    623                           false /* verify_to_dump */,
    624                           false /* allow_thread_suspension */);
    625   verifier.interesting_dex_pc_ = dex_pc;
    626   verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
    627   verifier.FindLocksAtDexPc();
    628 }
    629 
    630 void MethodVerifier::FindLocksAtDexPc() {
    631   CHECK(monitor_enter_dex_pcs_ != nullptr);
    632   CHECK(code_item_accessor_.HasCodeItem());  // This only makes sense for methods with code.
    633 
    634   // Quick check whether there are any monitor_enter instructions before verifying.
    635   for (const DexInstructionPcPair& inst : code_item_accessor_) {
    636     if (inst->Opcode() == Instruction::MONITOR_ENTER) {
    637       // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    638       // verification. In practice, the phase we want relies on data structures set up by all the
    639       // earlier passes, so we just run the full method verification and bail out early when we've
    640       // got what we wanted.
    641       Verify();
    642       return;
    643     }
    644   }
    645 }
    646 
    647 bool MethodVerifier::Verify() {
    648   // Some older code doesn't correctly mark constructors as such. Test for this case by looking at
    649   // the name.
    650   const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
    651   const char* method_name = dex_file_->StringDataByIdx(method_id.name_idx_);
    652   bool instance_constructor_by_name = strcmp("<init>", method_name) == 0;
    653   bool static_constructor_by_name = strcmp("<clinit>", method_name) == 0;
    654   bool constructor_by_name = instance_constructor_by_name || static_constructor_by_name;
    655   // Check that only constructors are tagged, and check for bad code that doesn't tag constructors.
    656   if ((method_access_flags_ & kAccConstructor) != 0) {
    657     if (!constructor_by_name) {
    658       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    659             << "method is marked as constructor, but not named accordingly";
    660       return false;
    661     }
    662     is_constructor_ = true;
    663   } else if (constructor_by_name) {
    664     LOG(WARNING) << "Method " << dex_file_->PrettyMethod(dex_method_idx_)
    665                  << " not marked as constructor.";
    666     is_constructor_ = true;
    667   }
    668   // If it's a constructor, check whether IsStatic() matches the name.
    669   // This should have been rejected by the dex file verifier. Only do in debug build.
    670   if (kIsDebugBuild) {
    671     if (IsConstructor()) {
    672       if (IsStatic() ^ static_constructor_by_name) {
    673         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    674               << "constructor name doesn't match static flag";
    675         return false;
    676       }
    677     }
    678   }
    679 
    680   // Methods may only have one of public/protected/private.
    681   // This should have been rejected by the dex file verifier. Only do in debug build.
    682   if (kIsDebugBuild) {
    683     size_t access_mod_count =
    684         (((method_access_flags_ & kAccPublic) == 0) ? 0 : 1) +
    685         (((method_access_flags_ & kAccProtected) == 0) ? 0 : 1) +
    686         (((method_access_flags_ & kAccPrivate) == 0) ? 0 : 1);
    687     if (access_mod_count > 1) {
    688       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "method has more than one of public/protected/private";
    689       return false;
    690     }
    691   }
    692 
    693   // If there aren't any instructions, make sure that's expected, then exit successfully.
    694   if (!code_item_accessor_.HasCodeItem()) {
    695     // Only native or abstract methods may not have code.
    696     if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) {
    697       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method";
    698       return false;
    699     }
    700 
    701     // This should have been rejected by the dex file verifier. Only do in debug build.
    702     // Note: the above will also be rejected in the dex file verifier, starting in dex version 37.
    703     if (kIsDebugBuild) {
    704       if ((method_access_flags_ & kAccAbstract) != 0) {
    705         // Abstract methods are not allowed to have the following flags.
    706         static constexpr uint32_t kForbidden =
    707             kAccPrivate |
    708             kAccStatic |
    709             kAccFinal |
    710             kAccNative |
    711             kAccStrict |
    712             kAccSynchronized;
    713         if ((method_access_flags_ & kForbidden) != 0) {
    714           Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    715                 << "method can't be abstract and private/static/final/native/strict/synchronized";
    716           return false;
    717         }
    718       }
    719       if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) {
    720         // Interface methods must be public and abstract (if default methods are disabled).
    721         uint32_t kRequired = kAccPublic;
    722         if ((method_access_flags_ & kRequired) != kRequired) {
    723           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods must be public";
    724           return false;
    725         }
    726         // In addition to the above, interface methods must not be protected.
    727         static constexpr uint32_t kForbidden = kAccProtected;
    728         if ((method_access_flags_ & kForbidden) != 0) {
    729           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods can't be protected";
    730           return false;
    731         }
    732       }
    733       // We also don't allow constructors to be abstract or native.
    734       if (IsConstructor()) {
    735         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be abstract or native";
    736         return false;
    737       }
    738     }
    739     return true;
    740   }
    741 
    742   // This should have been rejected by the dex file verifier. Only do in debug build.
    743   if (kIsDebugBuild) {
    744     // When there's code, the method must not be native or abstract.
    745     if ((method_access_flags_ & (kAccNative | kAccAbstract)) != 0) {
    746       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "non-zero-length code in abstract or native method";
    747       return false;
    748     }
    749 
    750     if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) {
    751       // Interfaces may always have static initializers for their fields. If we are running with
    752       // default methods enabled we also allow other public, static, non-final methods to have code.
    753       // Otherwise that is the only type of method allowed.
    754       if (!(IsConstructor() && IsStatic())) {
    755         if (IsInstanceConstructor()) {
    756           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-static constructor";
    757           return false;
    758         } else if (method_access_flags_ & kAccFinal) {
    759           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods";
    760           return false;
    761         } else {
    762           uint32_t access_flag_options = kAccPublic;
    763           if (dex_file_->SupportsDefaultMethods()) {
    764             access_flag_options |= kAccPrivate;
    765           }
    766           if (!(method_access_flags_ & access_flag_options)) {
    767             Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    768                 << "interfaces may not have protected or package-private members";
    769             return false;
    770           }
    771         }
    772       }
    773     }
    774 
    775     // Instance constructors must not be synchronized.
    776     if (IsInstanceConstructor()) {
    777       static constexpr uint32_t kForbidden = kAccSynchronized;
    778       if ((method_access_flags_ & kForbidden) != 0) {
    779         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be synchronized";
    780         return false;
    781       }
    782     }
    783   }
    784 
    785   // Sanity-check the register counts. ins + locals = registers, so make sure that ins <= registers.
    786   if (code_item_accessor_.InsSize() > code_item_accessor_.RegistersSize()) {
    787     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins="
    788                                       << code_item_accessor_.InsSize()
    789                                       << " regs=" << code_item_accessor_.RegistersSize();
    790     return false;
    791   }
    792 
    793   // Allocate and initialize an array to hold instruction data.
    794   insn_flags_.reset(allocator_.AllocArray<InstructionFlags>(
    795       code_item_accessor_.InsnsSizeInCodeUnits()));
    796   DCHECK(insn_flags_ != nullptr);
    797   std::uninitialized_fill_n(insn_flags_.get(),
    798                             code_item_accessor_.InsnsSizeInCodeUnits(),
    799                             InstructionFlags());
    800   // Run through the instructions and see if the width checks out.
    801   bool result = ComputeWidthsAndCountOps();
    802   bool allow_runtime_only_instructions = !Runtime::Current()->IsAotCompiler() || verify_to_dump_;
    803   // Flag instructions guarded by a "try" block and check exception handlers.
    804   result = result && ScanTryCatchBlocks();
    805   // Perform static instruction verification.
    806   result = result && (allow_runtime_only_instructions
    807                           ? VerifyInstructions<true>()
    808                           : VerifyInstructions<false>());
    809   // Perform code-flow analysis and return.
    810   result = result && VerifyCodeFlow();
    811 
    812   return result;
    813 }
    814 
    815 std::ostream& MethodVerifier::Fail(VerifyError error) {
    816   // Mark the error type as encountered.
    817   encountered_failure_types_ |= static_cast<uint32_t>(error);
    818 
    819   switch (error) {
    820     case VERIFY_ERROR_NO_CLASS:
    821     case VERIFY_ERROR_NO_FIELD:
    822     case VERIFY_ERROR_NO_METHOD:
    823     case VERIFY_ERROR_ACCESS_CLASS:
    824     case VERIFY_ERROR_ACCESS_FIELD:
    825     case VERIFY_ERROR_ACCESS_METHOD:
    826     case VERIFY_ERROR_INSTANTIATION:
    827     case VERIFY_ERROR_CLASS_CHANGE:
    828     case VERIFY_ERROR_FORCE_INTERPRETER:
    829     case VERIFY_ERROR_LOCKING:
    830       if (Runtime::Current()->IsAotCompiler() || !can_load_classes_) {
    831         // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx,
    832         // class change and instantiation errors into soft verification errors so that we re-verify
    833         // at runtime. We may fail to find or to agree on access because of not yet available class
    834         // loaders, or class loaders that will differ at runtime. In these cases, we don't want to
    835         // affect the soundness of the code being compiled. Instead, the generated code runs "slow
    836         // paths" that dynamically perform the verification and cause the behavior to be that akin
    837         // to an interpreter.
    838         error = VERIFY_ERROR_BAD_CLASS_SOFT;
    839       } else {
    840         // If we fail again at runtime, mark that this instruction would throw and force this
    841         // method to be executed using the interpreter with checks.
    842         have_pending_runtime_throw_failure_ = true;
    843 
    844         // We need to save the work_line if the instruction wasn't throwing before. Otherwise we'll
    845         // try to merge garbage.
    846         // Note: this assumes that Fail is called before we do any work_line modifications.
    847         // Note: this can fail before we touch any instruction, for the signature of a method. So
    848         //       add a check.
    849         if (work_insn_idx_ < dex::kDexNoIndex) {
    850           const Instruction& inst = code_item_accessor_.InstructionAt(work_insn_idx_);
    851           int opcode_flags = Instruction::FlagsOf(inst.Opcode());
    852 
    853           if ((opcode_flags & Instruction::kThrow) == 0 && CurrentInsnFlags()->IsInTry()) {
    854             saved_line_->CopyFromLine(work_line_.get());
    855           }
    856         }
    857       }
    858       break;
    859 
    860       // Indication that verification should be retried at runtime.
    861     case VERIFY_ERROR_BAD_CLASS_SOFT:
    862       if (!allow_soft_failures_) {
    863         have_pending_hard_failure_ = true;
    864       }
    865       break;
    866 
    867       // Hard verification failures at compile time will still fail at runtime, so the class is
    868       // marked as rejected to prevent it from being compiled.
    869     case VERIFY_ERROR_BAD_CLASS_HARD: {
    870       have_pending_hard_failure_ = true;
    871       if (VLOG_IS_ON(verifier) && kDumpRegLinesOnHardFailureIfVLOG) {
    872         ScopedObjectAccess soa(Thread::Current());
    873         std::ostringstream oss;
    874         Dump(oss);
    875         LOG(ERROR) << oss.str();
    876       }
    877       break;
    878     }
    879   }
    880   failures_.push_back(error);
    881   std::string location(StringPrintf("%s: [0x%X] ", dex_file_->PrettyMethod(dex_method_idx_).c_str(),
    882                                     work_insn_idx_));
    883   std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate);
    884   failure_messages_.push_back(failure_message);
    885   return *failure_message;
    886 }
    887 
    888 std::ostream& MethodVerifier::LogVerifyInfo() {
    889   return info_messages_ << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_)
    890                         << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
    891 }
    892 
    893 void MethodVerifier::PrependToLastFailMessage(std::string prepend) {
    894   size_t failure_num = failure_messages_.size();
    895   DCHECK_NE(failure_num, 0U);
    896   std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
    897   prepend += last_fail_message->str();
    898   failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate);
    899   delete last_fail_message;
    900 }
    901 
    902 void MethodVerifier::AppendToLastFailMessage(const std::string& append) {
    903   size_t failure_num = failure_messages_.size();
    904   DCHECK_NE(failure_num, 0U);
    905   std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
    906   (*last_fail_message) << append;
    907 }
    908 
    909 bool MethodVerifier::ComputeWidthsAndCountOps() {
    910   size_t new_instance_count = 0;
    911   size_t monitor_enter_count = 0;
    912 
    913   // We can't assume the instruction is well formed, handle the case where calculating the size
    914   // goes past the end of the code item.
    915   SafeDexInstructionIterator it(code_item_accessor_.begin(), code_item_accessor_.end());
    916   for ( ; !it.IsErrorState() && it < code_item_accessor_.end(); ++it) {
    917     // In case the instruction goes past the end of the code item, make sure to not process it.
    918     SafeDexInstructionIterator next = it;
    919     ++next;
    920     if (next.IsErrorState()) {
    921       break;
    922     }
    923     Instruction::Code opcode = it->Opcode();
    924     switch (opcode) {
    925       case Instruction::APUT_OBJECT:
    926       case Instruction::CHECK_CAST:
    927         has_check_casts_ = true;
    928         break;
    929       case Instruction::INVOKE_VIRTUAL:
    930       case Instruction::INVOKE_VIRTUAL_RANGE:
    931       case Instruction::INVOKE_INTERFACE:
    932       case Instruction::INVOKE_INTERFACE_RANGE:
    933         has_virtual_or_interface_invokes_ = true;
    934         break;
    935       case Instruction::MONITOR_ENTER:
    936         monitor_enter_count++;
    937         break;
    938       case Instruction::NEW_INSTANCE:
    939         new_instance_count++;
    940         break;
    941       default:
    942         break;
    943     }
    944     GetInstructionFlags(it.DexPc()).SetIsOpcode();
    945   }
    946 
    947   if (it != code_item_accessor_.end()) {
    948     const size_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits();
    949     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected ("
    950                                       << it.DexPc() << " vs. " << insns_size << ")";
    951     return false;
    952   }
    953 
    954   new_instance_count_ = new_instance_count;
    955   monitor_enter_count_ = monitor_enter_count;
    956   return true;
    957 }
    958 
    959 bool MethodVerifier::ScanTryCatchBlocks() {
    960   const uint32_t tries_size = code_item_accessor_.TriesSize();
    961   if (tries_size == 0) {
    962     return true;
    963   }
    964   const uint32_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits();
    965   for (const DexFile::TryItem& try_item : code_item_accessor_.TryItems()) {
    966     const uint32_t start = try_item.start_addr_;
    967     const uint32_t end = start + try_item.insn_count_;
    968     if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
    969       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start
    970                                         << " endAddr=" << end << " (size=" << insns_size << ")";
    971       return false;
    972     }
    973     if (!GetInstructionFlags(start).IsOpcode()) {
    974       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    975           << "'try' block starts inside an instruction (" << start << ")";
    976       return false;
    977     }
    978     DexInstructionIterator end_it(code_item_accessor_.Insns(), end);
    979     for (DexInstructionIterator it(code_item_accessor_.Insns(), start); it < end_it; ++it) {
    980       GetInstructionFlags(it.DexPc()).SetInTry();
    981     }
    982   }
    983   // Iterate over each of the handlers to verify target addresses.
    984   const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
    985   const uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
    986   ClassLinker* linker = Runtime::Current()->GetClassLinker();
    987   for (uint32_t idx = 0; idx < handlers_size; idx++) {
    988     CatchHandlerIterator iterator(handlers_ptr);
    989     for (; iterator.HasNext(); iterator.Next()) {
    990       uint32_t dex_pc = iterator.GetHandlerAddress();
    991       if (!GetInstructionFlags(dex_pc).IsOpcode()) {
    992         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    993             << "exception handler starts at bad address (" << dex_pc << ")";
    994         return false;
    995       }
    996       if (!CheckNotMoveResult(code_item_accessor_.Insns(), dex_pc)) {
    997         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    998             << "exception handler begins with move-result* (" << dex_pc << ")";
    999         return false;
   1000       }
   1001       GetInstructionFlags(dex_pc).SetBranchTarget();
   1002       // Ensure exception types are resolved so that they don't need resolution to be delivered,
   1003       // unresolved exception types will be ignored by exception delivery
   1004       if (iterator.GetHandlerTypeIndex().IsValid()) {
   1005         ObjPtr<mirror::Class> exception_type =
   1006             linker->ResolveType(iterator.GetHandlerTypeIndex(), dex_cache_, class_loader_);
   1007         if (exception_type == nullptr) {
   1008           DCHECK(self_->IsExceptionPending());
   1009           self_->ClearException();
   1010         }
   1011       }
   1012     }
   1013     handlers_ptr = iterator.EndDataPointer();
   1014   }
   1015   return true;
   1016 }
   1017 
   1018 template <bool kAllowRuntimeOnlyInstructions>
   1019 bool MethodVerifier::VerifyInstructions() {
   1020   /* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */
   1021   GetInstructionFlags(0).SetBranchTarget();
   1022   GetInstructionFlags(0).SetCompileTimeInfoPoint();
   1023   for (const DexInstructionPcPair& inst : code_item_accessor_) {
   1024     const uint32_t dex_pc = inst.DexPc();
   1025     if (!VerifyInstruction<kAllowRuntimeOnlyInstructions>(&inst.Inst(), dex_pc)) {
   1026       DCHECK_NE(failures_.size(), 0U);
   1027       return false;
   1028     }
   1029     /* Flag instructions that are garbage collection points */
   1030     // All invoke points are marked as "Throw" points already.
   1031     // We are relying on this to also count all the invokes as interesting.
   1032     if (inst->IsBranch()) {
   1033       GetInstructionFlags(dex_pc).SetCompileTimeInfoPoint();
   1034       // The compiler also needs safepoints for fall-through to loop heads.
   1035       // Such a loop head must be a target of a branch.
   1036       int32_t offset = 0;
   1037       bool cond, self_ok;
   1038       bool target_ok = GetBranchOffset(dex_pc, &offset, &cond, &self_ok);
   1039       DCHECK(target_ok);
   1040       GetInstructionFlags(dex_pc + offset).SetCompileTimeInfoPoint();
   1041     } else if (inst->IsSwitch() || inst->IsThrow()) {
   1042       GetInstructionFlags(dex_pc).SetCompileTimeInfoPoint();
   1043     } else if (inst->IsReturn()) {
   1044       GetInstructionFlags(dex_pc).SetCompileTimeInfoPointAndReturn();
   1045     }
   1046   }
   1047   return true;
   1048 }
   1049 
   1050 template <bool kAllowRuntimeOnlyInstructions>
   1051 bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_offset) {
   1052   if (Instruction::kHaveExperimentalInstructions && UNLIKELY(inst->IsExperimental())) {
   1053     // Experimental instructions don't yet have verifier support implementation.
   1054     // While it is possible to use them by themselves, when we try to use stable instructions
   1055     // with a virtual register that was created by an experimental instruction,
   1056     // the data flow analysis will fail.
   1057     Fail(VERIFY_ERROR_FORCE_INTERPRETER)
   1058         << "experimental instruction is not supported by verifier; skipping verification";
   1059     have_pending_experimental_failure_ = true;
   1060     return false;
   1061   }
   1062 
   1063   bool result = true;
   1064   switch (inst->GetVerifyTypeArgumentA()) {
   1065     case Instruction::kVerifyRegA:
   1066       result = result && CheckRegisterIndex(inst->VRegA());
   1067       break;
   1068     case Instruction::kVerifyRegAWide:
   1069       result = result && CheckWideRegisterIndex(inst->VRegA());
   1070       break;
   1071   }
   1072   switch (inst->GetVerifyTypeArgumentB()) {
   1073     case Instruction::kVerifyRegB:
   1074       result = result && CheckRegisterIndex(inst->VRegB());
   1075       break;
   1076     case Instruction::kVerifyRegBField:
   1077       result = result && CheckFieldIndex(inst->VRegB());
   1078       break;
   1079     case Instruction::kVerifyRegBMethod:
   1080       result = result && CheckMethodIndex(inst->VRegB());
   1081       break;
   1082     case Instruction::kVerifyRegBNewInstance:
   1083       result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB()));
   1084       break;
   1085     case Instruction::kVerifyRegBString:
   1086       result = result && CheckStringIndex(inst->VRegB());
   1087       break;
   1088     case Instruction::kVerifyRegBType:
   1089       result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB()));
   1090       break;
   1091     case Instruction::kVerifyRegBWide:
   1092       result = result && CheckWideRegisterIndex(inst->VRegB());
   1093       break;
   1094     case Instruction::kVerifyRegBCallSite:
   1095       result = result && CheckCallSiteIndex(inst->VRegB());
   1096       break;
   1097     case Instruction::kVerifyRegBMethodHandle:
   1098       result = result && CheckMethodHandleIndex(inst->VRegB());
   1099       break;
   1100     case Instruction::kVerifyRegBPrototype:
   1101       result = result && CheckPrototypeIndex(inst->VRegB());
   1102       break;
   1103   }
   1104   switch (inst->GetVerifyTypeArgumentC()) {
   1105     case Instruction::kVerifyRegC:
   1106       result = result && CheckRegisterIndex(inst->VRegC());
   1107       break;
   1108     case Instruction::kVerifyRegCField:
   1109       result = result && CheckFieldIndex(inst->VRegC());
   1110       break;
   1111     case Instruction::kVerifyRegCNewArray:
   1112       result = result && CheckNewArray(dex::TypeIndex(inst->VRegC()));
   1113       break;
   1114     case Instruction::kVerifyRegCType:
   1115       result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC()));
   1116       break;
   1117     case Instruction::kVerifyRegCWide:
   1118       result = result && CheckWideRegisterIndex(inst->VRegC());
   1119       break;
   1120   }
   1121   switch (inst->GetVerifyTypeArgumentH()) {
   1122     case Instruction::kVerifyRegHPrototype:
   1123       result = result && CheckPrototypeIndex(inst->VRegH());
   1124       break;
   1125   }
   1126   switch (inst->GetVerifyExtraFlags()) {
   1127     case Instruction::kVerifyArrayData:
   1128       result = result && CheckArrayData(code_offset);
   1129       break;
   1130     case Instruction::kVerifyBranchTarget:
   1131       result = result && CheckBranchTarget(code_offset);
   1132       break;
   1133     case Instruction::kVerifySwitchTargets:
   1134       result = result && CheckSwitchTargets(code_offset);
   1135       break;
   1136     case Instruction::kVerifyVarArgNonZero:
   1137       // Fall-through.
   1138     case Instruction::kVerifyVarArg: {
   1139       // Instructions that can actually return a negative value shouldn't have this flag.
   1140       uint32_t v_a = dchecked_integral_cast<uint32_t>(inst->VRegA());
   1141       if ((inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && v_a == 0) ||
   1142           v_a > Instruction::kMaxVarArgRegs) {
   1143         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << v_a << ") in "
   1144                                              "non-range invoke";
   1145         return false;
   1146       }
   1147 
   1148       uint32_t args[Instruction::kMaxVarArgRegs];
   1149       inst->GetVarArgs(args);
   1150       result = result && CheckVarArgRegs(v_a, args);
   1151       break;
   1152     }
   1153     case Instruction::kVerifyVarArgRangeNonZero:
   1154       // Fall-through.
   1155     case Instruction::kVerifyVarArgRange:
   1156       if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero &&
   1157           inst->VRegA() <= 0) {
   1158         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
   1159                                              "range invoke";
   1160         return false;
   1161       }
   1162       result = result && CheckVarArgRangeRegs(inst->VRegA(), inst->VRegC());
   1163       break;
   1164     case Instruction::kVerifyError:
   1165       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name();
   1166       result = false;
   1167       break;
   1168   }
   1169   if (!kAllowRuntimeOnlyInstructions && inst->GetVerifyIsRuntimeOnly()) {
   1170     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "opcode only expected at runtime " << inst->Name();
   1171     result = false;
   1172   }
   1173   return result;
   1174 }
   1175 
   1176 inline bool MethodVerifier::CheckRegisterIndex(uint32_t idx) {
   1177   if (UNLIKELY(idx >= code_item_accessor_.RegistersSize())) {
   1178     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= "
   1179                                       << code_item_accessor_.RegistersSize() << ")";
   1180     return false;
   1181   }
   1182   return true;
   1183 }
   1184 
   1185 inline bool MethodVerifier::CheckWideRegisterIndex(uint32_t idx) {
   1186   if (UNLIKELY(idx + 1 >= code_item_accessor_.RegistersSize())) {
   1187     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx
   1188                                       << "+1 >= " << code_item_accessor_.RegistersSize() << ")";
   1189     return false;
   1190   }
   1191   return true;
   1192 }
   1193 
   1194 inline bool MethodVerifier::CheckCallSiteIndex(uint32_t idx) {
   1195   uint32_t limit = dex_file_->NumCallSiteIds();
   1196   if (UNLIKELY(idx >= limit)) {
   1197     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad call site index " << idx << " (max "
   1198                                       << limit << ")";
   1199     return false;
   1200   }
   1201   return true;
   1202 }
   1203 
   1204 inline bool MethodVerifier::CheckFieldIndex(uint32_t idx) {
   1205   if (UNLIKELY(idx >= dex_file_->GetHeader().field_ids_size_)) {
   1206     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad field index " << idx << " (max "
   1207                                       << dex_file_->GetHeader().field_ids_size_ << ")";
   1208     return false;
   1209   }
   1210   return true;
   1211 }
   1212 
   1213 inline bool MethodVerifier::CheckMethodIndex(uint32_t idx) {
   1214   if (UNLIKELY(idx >= dex_file_->GetHeader().method_ids_size_)) {
   1215     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method index " << idx << " (max "
   1216                                       << dex_file_->GetHeader().method_ids_size_ << ")";
   1217     return false;
   1218   }
   1219   return true;
   1220 }
   1221 
   1222 inline bool MethodVerifier::CheckMethodHandleIndex(uint32_t idx) {
   1223   uint32_t limit = dex_file_->NumMethodHandles();
   1224   if (UNLIKELY(idx >= limit)) {
   1225     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method handle index " << idx << " (max "
   1226                                       << limit << ")";
   1227     return false;
   1228   }
   1229   return true;
   1230 }
   1231 
   1232 inline bool MethodVerifier::CheckNewInstance(dex::TypeIndex idx) {
   1233   if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) {
   1234     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
   1235                                       << dex_file_->GetHeader().type_ids_size_ << ")";
   1236     return false;
   1237   }
   1238   // We don't need the actual class, just a pointer to the class name.
   1239   const char* descriptor = dex_file_->StringByTypeIdx(idx);
   1240   if (UNLIKELY(descriptor[0] != 'L')) {
   1241     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'";
   1242     return false;
   1243   } else if (UNLIKELY(strcmp(descriptor, "Ljava/lang/Class;") == 0)) {
   1244     // An unlikely new instance on Class is not allowed. Fall back to interpreter to ensure an
   1245     // exception is thrown when this statement is executed (compiled code would not do that).
   1246     Fail(VERIFY_ERROR_INSTANTIATION);
   1247   }
   1248   return true;
   1249 }
   1250 
   1251 inline bool MethodVerifier::CheckPrototypeIndex(uint32_t idx) {
   1252   if (UNLIKELY(idx >= dex_file_->GetHeader().proto_ids_size_)) {
   1253     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad prototype index " << idx << " (max "
   1254                                       << dex_file_->GetHeader().proto_ids_size_ << ")";
   1255     return false;
   1256   }
   1257   return true;
   1258 }
   1259 
   1260 inline bool MethodVerifier::CheckStringIndex(uint32_t idx) {
   1261   if (UNLIKELY(idx >= dex_file_->GetHeader().string_ids_size_)) {
   1262     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max "
   1263                                       << dex_file_->GetHeader().string_ids_size_ << ")";
   1264     return false;
   1265   }
   1266   return true;
   1267 }
   1268 
   1269 inline bool MethodVerifier::CheckTypeIndex(dex::TypeIndex idx) {
   1270   if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) {
   1271     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
   1272                                       << dex_file_->GetHeader().type_ids_size_ << ")";
   1273     return false;
   1274   }
   1275   return true;
   1276 }
   1277 
   1278 bool MethodVerifier::CheckNewArray(dex::TypeIndex idx) {
   1279   if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) {
   1280     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
   1281                                       << dex_file_->GetHeader().type_ids_size_ << ")";
   1282     return false;
   1283   }
   1284   int bracket_count = 0;
   1285   const char* descriptor = dex_file_->StringByTypeIdx(idx);
   1286   const char* cp = descriptor;
   1287   while (*cp++ == '[') {
   1288     bracket_count++;
   1289   }
   1290   if (UNLIKELY(bracket_count == 0)) {
   1291     /* The given class must be an array type. */
   1292     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1293         << "can't new-array class '" << descriptor << "' (not an array)";
   1294     return false;
   1295   } else if (UNLIKELY(bracket_count > 255)) {
   1296     /* It is illegal to create an array of more than 255 dimensions. */
   1297     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1298         << "can't new-array class '" << descriptor << "' (exceeds limit)";
   1299     return false;
   1300   }
   1301   return true;
   1302 }
   1303 
   1304 bool MethodVerifier::CheckArrayData(uint32_t cur_offset) {
   1305   const uint32_t insn_count = code_item_accessor_.InsnsSizeInCodeUnits();
   1306   const uint16_t* insns = code_item_accessor_.Insns() + cur_offset;
   1307   const uint16_t* array_data;
   1308   int32_t array_data_offset;
   1309 
   1310   DCHECK_LT(cur_offset, insn_count);
   1311   /* make sure the start of the array data table is in range */
   1312   array_data_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
   1313   if (UNLIKELY(static_cast<int32_t>(cur_offset) + array_data_offset < 0 ||
   1314                cur_offset + array_data_offset + 2 >= insn_count)) {
   1315     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset
   1316                                       << ", data offset " << array_data_offset
   1317                                       << ", count " << insn_count;
   1318     return false;
   1319   }
   1320   /* offset to array data table is a relative branch-style offset */
   1321   array_data = insns + array_data_offset;
   1322   // Make sure the table is at an even dex pc, that is, 32-bit aligned.
   1323   if (UNLIKELY(!IsAligned<4>(array_data))) {
   1324     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset
   1325                                       << ", data offset " << array_data_offset;
   1326     return false;
   1327   }
   1328   // Make sure the array-data is marked as an opcode. This ensures that it was reached when
   1329   // traversing the code item linearly. It is an approximation for a by-spec padding value.
   1330   if (UNLIKELY(!GetInstructionFlags(cur_offset + array_data_offset).IsOpcode())) {
   1331     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array data table at " << cur_offset
   1332                                       << ", data offset " << array_data_offset
   1333                                       << " not correctly visited, probably bad padding.";
   1334     return false;
   1335   }
   1336 
   1337   uint32_t value_width = array_data[1];
   1338   uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]);
   1339   uint32_t table_size = 4 + (value_width * value_count + 1) / 2;
   1340   /* make sure the end of the switch is in range */
   1341   if (UNLIKELY(cur_offset + array_data_offset + table_size > insn_count)) {
   1342     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset
   1343                                       << ", data offset " << array_data_offset << ", end "
   1344                                       << cur_offset + array_data_offset + table_size
   1345                                       << ", count " << insn_count;
   1346     return false;
   1347   }
   1348   return true;
   1349 }
   1350 
   1351 bool MethodVerifier::CheckBranchTarget(uint32_t cur_offset) {
   1352   int32_t offset;
   1353   bool isConditional, selfOkay;
   1354   if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) {
   1355     return false;
   1356   }
   1357   if (UNLIKELY(!selfOkay && offset == 0)) {
   1358     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at"
   1359                                       << reinterpret_cast<void*>(cur_offset);
   1360     return false;
   1361   }
   1362   // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime
   1363   // to have identical "wrap-around" behavior, but it's unwise to depend on that.
   1364   if (UNLIKELY(((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset))) {
   1365     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow "
   1366                                       << reinterpret_cast<void*>(cur_offset) << " +" << offset;
   1367     return false;
   1368   }
   1369   int32_t abs_offset = cur_offset + offset;
   1370   if (UNLIKELY(abs_offset < 0 ||
   1371                (uint32_t) abs_offset >= code_item_accessor_.InsnsSizeInCodeUnits()  ||
   1372                !GetInstructionFlags(abs_offset).IsOpcode())) {
   1373     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> "
   1374                                       << reinterpret_cast<void*>(abs_offset) << ") at "
   1375                                       << reinterpret_cast<void*>(cur_offset);
   1376     return false;
   1377   }
   1378   GetInstructionFlags(abs_offset).SetBranchTarget();
   1379   return true;
   1380 }
   1381 
   1382 bool MethodVerifier::GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional,
   1383                                   bool* selfOkay) {
   1384   const uint16_t* insns = code_item_accessor_.Insns() + cur_offset;
   1385   *pConditional = false;
   1386   *selfOkay = false;
   1387   switch (*insns & 0xff) {
   1388     case Instruction::GOTO:
   1389       *pOffset = ((int16_t) *insns) >> 8;
   1390       break;
   1391     case Instruction::GOTO_32:
   1392       *pOffset = insns[1] | (((uint32_t) insns[2]) << 16);
   1393       *selfOkay = true;
   1394       break;
   1395     case Instruction::GOTO_16:
   1396       *pOffset = (int16_t) insns[1];
   1397       break;
   1398     case Instruction::IF_EQ:
   1399     case Instruction::IF_NE:
   1400     case Instruction::IF_LT:
   1401     case Instruction::IF_GE:
   1402     case Instruction::IF_GT:
   1403     case Instruction::IF_LE:
   1404     case Instruction::IF_EQZ:
   1405     case Instruction::IF_NEZ:
   1406     case Instruction::IF_LTZ:
   1407     case Instruction::IF_GEZ:
   1408     case Instruction::IF_GTZ:
   1409     case Instruction::IF_LEZ:
   1410       *pOffset = (int16_t) insns[1];
   1411       *pConditional = true;
   1412       break;
   1413     default:
   1414       return false;
   1415   }
   1416   return true;
   1417 }
   1418 
   1419 bool MethodVerifier::CheckSwitchTargets(uint32_t cur_offset) {
   1420   const uint32_t insn_count = code_item_accessor_.InsnsSizeInCodeUnits();
   1421   DCHECK_LT(cur_offset, insn_count);
   1422   const uint16_t* insns = code_item_accessor_.Insns() + cur_offset;
   1423   /* make sure the start of the switch is in range */
   1424   int32_t switch_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
   1425   if (UNLIKELY(static_cast<int32_t>(cur_offset) + switch_offset < 0 ||
   1426                cur_offset + switch_offset + 2 > insn_count)) {
   1427     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset
   1428                                       << ", switch offset " << switch_offset
   1429                                       << ", count " << insn_count;
   1430     return false;
   1431   }
   1432   /* offset to switch table is a relative branch-style offset */
   1433   const uint16_t* switch_insns = insns + switch_offset;
   1434   // Make sure the table is at an even dex pc, that is, 32-bit aligned.
   1435   if (UNLIKELY(!IsAligned<4>(switch_insns))) {
   1436     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset
   1437                                       << ", switch offset " << switch_offset;
   1438     return false;
   1439   }
   1440   // Make sure the switch data is marked as an opcode. This ensures that it was reached when
   1441   // traversing the code item linearly. It is an approximation for a by-spec padding value.
   1442   if (UNLIKELY(!GetInstructionFlags(cur_offset + switch_offset).IsOpcode())) {
   1443     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "switch table at " << cur_offset
   1444                                       << ", switch offset " << switch_offset
   1445                                       << " not correctly visited, probably bad padding.";
   1446     return false;
   1447   }
   1448 
   1449   bool is_packed_switch = (*insns & 0xff) == Instruction::PACKED_SWITCH;
   1450 
   1451   uint32_t switch_count = switch_insns[1];
   1452   int32_t targets_offset;
   1453   uint16_t expected_signature;
   1454   if (is_packed_switch) {
   1455     /* 0=sig, 1=count, 2/3=firstKey */
   1456     targets_offset = 4;
   1457     expected_signature = Instruction::kPackedSwitchSignature;
   1458   } else {
   1459     /* 0=sig, 1=count, 2..count*2 = keys */
   1460     targets_offset = 2 + 2 * switch_count;
   1461     expected_signature = Instruction::kSparseSwitchSignature;
   1462   }
   1463   uint32_t table_size = targets_offset + switch_count * 2;
   1464   if (UNLIKELY(switch_insns[0] != expected_signature)) {
   1465     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1466         << StringPrintf("wrong signature for switch table (%x, wanted %x)",
   1467                         switch_insns[0], expected_signature);
   1468     return false;
   1469   }
   1470   /* make sure the end of the switch is in range */
   1471   if (UNLIKELY(cur_offset + switch_offset + table_size > (uint32_t) insn_count)) {
   1472     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset
   1473                                       << ", switch offset " << switch_offset
   1474                                       << ", end " << (cur_offset + switch_offset + table_size)
   1475                                       << ", count " << insn_count;
   1476     return false;
   1477   }
   1478 
   1479   constexpr int32_t keys_offset = 2;
   1480   if (switch_count > 1) {
   1481     if (is_packed_switch) {
   1482       /* for a packed switch, verify that keys do not overflow int32 */
   1483       int32_t first_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
   1484       int32_t max_first_key =
   1485           std::numeric_limits<int32_t>::max() - (static_cast<int32_t>(switch_count) - 1);
   1486       if (UNLIKELY(first_key > max_first_key)) {
   1487         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: first_key=" << first_key
   1488                                           << ", switch_count=" << switch_count;
   1489         return false;
   1490       }
   1491     } else {
   1492       /* for a sparse switch, verify the keys are in ascending order */
   1493       int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
   1494       for (uint32_t targ = 1; targ < switch_count; targ++) {
   1495         int32_t key =
   1496             static_cast<int32_t>(switch_insns[keys_offset + targ * 2]) |
   1497             static_cast<int32_t>(switch_insns[keys_offset + targ * 2 + 1] << 16);
   1498         if (UNLIKELY(key <= last_key)) {
   1499           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid sparse switch: last key=" << last_key
   1500                                             << ", this=" << key;
   1501           return false;
   1502         }
   1503         last_key = key;
   1504       }
   1505     }
   1506   }
   1507   /* verify each switch target */
   1508   for (uint32_t targ = 0; targ < switch_count; targ++) {
   1509     int32_t offset = static_cast<int32_t>(switch_insns[targets_offset + targ * 2]) |
   1510                      static_cast<int32_t>(switch_insns[targets_offset + targ * 2 + 1] << 16);
   1511     int32_t abs_offset = cur_offset + offset;
   1512     if (UNLIKELY(abs_offset < 0 ||
   1513                  abs_offset >= static_cast<int32_t>(insn_count) ||
   1514                  !GetInstructionFlags(abs_offset).IsOpcode())) {
   1515       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset
   1516                                         << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at "
   1517                                         << reinterpret_cast<void*>(cur_offset)
   1518                                         << "[" << targ << "]";
   1519       return false;
   1520     }
   1521     GetInstructionFlags(abs_offset).SetBranchTarget();
   1522   }
   1523   return true;
   1524 }
   1525 
   1526 bool MethodVerifier::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) {
   1527   uint16_t registers_size = code_item_accessor_.RegistersSize();
   1528   for (uint32_t idx = 0; idx < vA; idx++) {
   1529     if (UNLIKELY(arg[idx] >= registers_size)) {
   1530       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index (" << arg[idx]
   1531                                         << ") in non-range invoke (>= " << registers_size << ")";
   1532       return false;
   1533     }
   1534   }
   1535 
   1536   return true;
   1537 }
   1538 
   1539 bool MethodVerifier::CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) {
   1540   uint16_t registers_size = code_item_accessor_.RegistersSize();
   1541   // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of
   1542   // integer overflow when adding them here.
   1543   if (UNLIKELY(vA + vC > registers_size)) {
   1544     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC
   1545                                       << " in range invoke (> " << registers_size << ")";
   1546     return false;
   1547   }
   1548   return true;
   1549 }
   1550 
   1551 bool MethodVerifier::VerifyCodeFlow() {
   1552   const uint16_t registers_size = code_item_accessor_.RegistersSize();
   1553 
   1554   /* Create and initialize table holding register status */
   1555   reg_table_.Init(kTrackCompilerInterestPoints,
   1556                   insn_flags_.get(),
   1557                   code_item_accessor_.InsnsSizeInCodeUnits(),
   1558                   registers_size,
   1559                   this);
   1560 
   1561   work_line_.reset(RegisterLine::Create(registers_size, this));
   1562   saved_line_.reset(RegisterLine::Create(registers_size, this));
   1563 
   1564   /* Initialize register types of method arguments. */
   1565   if (!SetTypesFromSignature()) {
   1566     DCHECK_NE(failures_.size(), 0U);
   1567     std::string prepend("Bad signature in ");
   1568     prepend += dex_file_->PrettyMethod(dex_method_idx_);
   1569     PrependToLastFailMessage(prepend);
   1570     return false;
   1571   }
   1572   // We may have a runtime failure here, clear.
   1573   have_pending_runtime_throw_failure_ = false;
   1574 
   1575   /* Perform code flow verification. */
   1576   if (!CodeFlowVerifyMethod()) {
   1577     DCHECK_NE(failures_.size(), 0U);
   1578     return false;
   1579   }
   1580   return true;
   1581 }
   1582 
   1583 std::ostream& MethodVerifier::DumpFailures(std::ostream& os) {
   1584   DCHECK_EQ(failures_.size(), failure_messages_.size());
   1585   for (size_t i = 0; i < failures_.size(); ++i) {
   1586       os << failure_messages_[i]->str() << "\n";
   1587   }
   1588   return os;
   1589 }
   1590 
   1591 void MethodVerifier::Dump(std::ostream& os) {
   1592   VariableIndentationOutputStream vios(&os);
   1593   Dump(&vios);
   1594 }
   1595 
   1596 void MethodVerifier::Dump(VariableIndentationOutputStream* vios) {
   1597   if (!code_item_accessor_.HasCodeItem()) {
   1598     vios->Stream() << "Native method\n";
   1599     return;
   1600   }
   1601   {
   1602     vios->Stream() << "Register Types:\n";
   1603     ScopedIndentation indent1(vios);
   1604     reg_types_.Dump(vios->Stream());
   1605   }
   1606   vios->Stream() << "Dumping instructions and register lines:\n";
   1607   ScopedIndentation indent1(vios);
   1608 
   1609   for (const DexInstructionPcPair& inst : code_item_accessor_) {
   1610     const size_t dex_pc = inst.DexPc();
   1611 
   1612     // Might be asked to dump before the table is initialized.
   1613     if (reg_table_.IsInitialized()) {
   1614       RegisterLine* reg_line = reg_table_.GetLine(dex_pc);
   1615       if (reg_line != nullptr) {
   1616         vios->Stream() << reg_line->Dump(this) << "\n";
   1617       }
   1618     }
   1619 
   1620     vios->Stream()
   1621         << StringPrintf("0x%04zx", dex_pc) << ": " << GetInstructionFlags(dex_pc).ToString() << " ";
   1622     const bool kDumpHexOfInstruction = false;
   1623     if (kDumpHexOfInstruction) {
   1624       vios->Stream() << inst->DumpHex(5) << " ";
   1625     }
   1626     vios->Stream() << inst->DumpString(dex_file_) << "\n";
   1627   }
   1628 }
   1629 
   1630 static bool IsPrimitiveDescriptor(char descriptor) {
   1631   switch (descriptor) {
   1632     case 'I':
   1633     case 'C':
   1634     case 'S':
   1635     case 'B':
   1636     case 'Z':
   1637     case 'F':
   1638     case 'D':
   1639     case 'J':
   1640       return true;
   1641     default:
   1642       return false;
   1643   }
   1644 }
   1645 
   1646 bool MethodVerifier::SetTypesFromSignature() {
   1647   RegisterLine* reg_line = reg_table_.GetLine(0);
   1648 
   1649   // Should have been verified earlier.
   1650   DCHECK_GE(code_item_accessor_.RegistersSize(), code_item_accessor_.InsSize());
   1651 
   1652   uint32_t arg_start = code_item_accessor_.RegistersSize() - code_item_accessor_.InsSize();
   1653   size_t expected_args = code_item_accessor_.InsSize();   /* long/double count as two */
   1654 
   1655   // Include the "this" pointer.
   1656   size_t cur_arg = 0;
   1657   if (!IsStatic()) {
   1658     if (expected_args == 0) {
   1659       // Expect at least a receiver.
   1660       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected 0 args, but method is not static";
   1661       return false;
   1662     }
   1663 
   1664     // If this is a constructor for a class other than java.lang.Object, mark the first ("this")
   1665     // argument as uninitialized. This restricts field access until the superclass constructor is
   1666     // called.
   1667     const RegType& declaring_class = GetDeclaringClass();
   1668     if (IsConstructor()) {
   1669       if (declaring_class.IsJavaLangObject()) {
   1670         // "this" is implicitly initialized.
   1671         reg_line->SetThisInitialized();
   1672         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class);
   1673       } else {
   1674         reg_line->SetRegisterType<LockOp::kClear>(
   1675             this,
   1676             arg_start + cur_arg,
   1677             reg_types_.UninitializedThisArgument(declaring_class));
   1678       }
   1679     } else {
   1680       reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class);
   1681     }
   1682     cur_arg++;
   1683   }
   1684 
   1685   const DexFile::ProtoId& proto_id =
   1686       dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
   1687   DexFileParameterIterator iterator(*dex_file_, proto_id);
   1688 
   1689   for (; iterator.HasNext(); iterator.Next()) {
   1690     const char* descriptor = iterator.GetDescriptor();
   1691     if (descriptor == nullptr) {
   1692       LOG(FATAL) << "Null descriptor";
   1693     }
   1694     if (cur_arg >= expected_args) {
   1695       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1696                                         << " args, found more (" << descriptor << ")";
   1697       return false;
   1698     }
   1699     switch (descriptor[0]) {
   1700       case 'L':
   1701       case '[':
   1702         // We assume that reference arguments are initialized. The only way it could be otherwise
   1703         // (assuming the caller was verified) is if the current method is <init>, but in that case
   1704         // it's effectively considered initialized the instant we reach here (in the sense that we
   1705         // can return without doing anything or call virtual methods).
   1706         {
   1707           // Note: don't check access. No error would be thrown for declaring or passing an
   1708           //       inaccessible class. Only actual accesses to fields or methods will.
   1709           const RegType& reg_type = ResolveClass<CheckAccess::kNo>(iterator.GetTypeIdx());
   1710           if (!reg_type.IsNonZeroReferenceTypes()) {
   1711             DCHECK(HasFailures());
   1712             return false;
   1713           }
   1714           reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_type);
   1715         }
   1716         break;
   1717       case 'Z':
   1718         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Boolean());
   1719         break;
   1720       case 'C':
   1721         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Char());
   1722         break;
   1723       case 'B':
   1724         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Byte());
   1725         break;
   1726       case 'I':
   1727         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Integer());
   1728         break;
   1729       case 'S':
   1730         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Short());
   1731         break;
   1732       case 'F':
   1733         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Float());
   1734         break;
   1735       case 'J':
   1736       case 'D': {
   1737         if (cur_arg + 1 >= expected_args) {
   1738           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1739               << " args, found more (" << descriptor << ")";
   1740           return false;
   1741         }
   1742 
   1743         const RegType* lo_half;
   1744         const RegType* hi_half;
   1745         if (descriptor[0] == 'J') {
   1746           lo_half = &reg_types_.LongLo();
   1747           hi_half = &reg_types_.LongHi();
   1748         } else {
   1749           lo_half = &reg_types_.DoubleLo();
   1750           hi_half = &reg_types_.DoubleHi();
   1751         }
   1752         reg_line->SetRegisterTypeWide(this, arg_start + cur_arg, *lo_half, *hi_half);
   1753         cur_arg++;
   1754         break;
   1755       }
   1756       default:
   1757         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '"
   1758                                           << descriptor << "'";
   1759         return false;
   1760     }
   1761     cur_arg++;
   1762   }
   1763   if (cur_arg != expected_args) {
   1764     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1765                                       << " arguments, found " << cur_arg;
   1766     return false;
   1767   }
   1768   const char* descriptor = dex_file_->GetReturnTypeDescriptor(proto_id);
   1769   // Validate return type. We don't do the type lookup; just want to make sure that it has the right
   1770   // format. Only major difference from the method argument format is that 'V' is supported.
   1771   bool result;
   1772   if (IsPrimitiveDescriptor(descriptor[0]) || descriptor[0] == 'V') {
   1773     result = descriptor[1] == '\0';
   1774   } else if (descriptor[0] == '[') {  // single/multi-dimensional array of object/primitive
   1775     size_t i = 0;
   1776     do {
   1777       i++;
   1778     } while (descriptor[i] == '[');  // process leading [
   1779     if (descriptor[i] == 'L') {  // object array
   1780       do {
   1781         i++;  // find closing ;
   1782       } while (descriptor[i] != ';' && descriptor[i] != '\0');
   1783       result = descriptor[i] == ';';
   1784     } else {  // primitive array
   1785       result = IsPrimitiveDescriptor(descriptor[i]) && descriptor[i + 1] == '\0';
   1786     }
   1787   } else if (descriptor[0] == 'L') {
   1788     // could be more thorough here, but shouldn't be required
   1789     size_t i = 0;
   1790     do {
   1791       i++;
   1792     } while (descriptor[i] != ';' && descriptor[i] != '\0');
   1793     result = descriptor[i] == ';';
   1794   } else {
   1795     result = false;
   1796   }
   1797   if (!result) {
   1798     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected char in return type descriptor '"
   1799                                       << descriptor << "'";
   1800   }
   1801   return result;
   1802 }
   1803 
   1804 bool MethodVerifier::CodeFlowVerifyMethod() {
   1805   const uint16_t* insns = code_item_accessor_.Insns();
   1806   const uint32_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits();
   1807 
   1808   /* Begin by marking the first instruction as "changed". */
   1809   GetInstructionFlags(0).SetChanged();
   1810   uint32_t start_guess = 0;
   1811 
   1812   /* Continue until no instructions are marked "changed". */
   1813   while (true) {
   1814     if (allow_thread_suspension_) {
   1815       self_->AllowThreadSuspension();
   1816     }
   1817     // Find the first marked one. Use "start_guess" as a way to find one quickly.
   1818     uint32_t insn_idx = start_guess;
   1819     for (; insn_idx < insns_size; insn_idx++) {
   1820       if (GetInstructionFlags(insn_idx).IsChanged())
   1821         break;
   1822     }
   1823     if (insn_idx == insns_size) {
   1824       if (start_guess != 0) {
   1825         /* try again, starting from the top */
   1826         start_guess = 0;
   1827         continue;
   1828       } else {
   1829         /* all flags are clear */
   1830         break;
   1831       }
   1832     }
   1833     // We carry the working set of registers from instruction to instruction. If this address can
   1834     // be the target of a branch (or throw) instruction, or if we're skipping around chasing
   1835     // "changed" flags, we need to load the set of registers from the table.
   1836     // Because we always prefer to continue on to the next instruction, we should never have a
   1837     // situation where we have a stray "changed" flag set on an instruction that isn't a branch
   1838     // target.
   1839     work_insn_idx_ = insn_idx;
   1840     if (GetInstructionFlags(insn_idx).IsBranchTarget()) {
   1841       work_line_->CopyFromLine(reg_table_.GetLine(insn_idx));
   1842     } else if (kIsDebugBuild) {
   1843       /*
   1844        * Sanity check: retrieve the stored register line (assuming
   1845        * a full table) and make sure it actually matches.
   1846        */
   1847       RegisterLine* register_line = reg_table_.GetLine(insn_idx);
   1848       if (register_line != nullptr) {
   1849         if (work_line_->CompareLine(register_line) != 0) {
   1850           Dump(std::cout);
   1851           std::cout << info_messages_.str();
   1852           LOG(FATAL) << "work_line diverged in " << dex_file_->PrettyMethod(dex_method_idx_)
   1853                      << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n"
   1854                      << " work_line=" << work_line_->Dump(this) << "\n"
   1855                      << "  expected=" << register_line->Dump(this);
   1856         }
   1857       }
   1858     }
   1859     if (!CodeFlowVerifyInstruction(&start_guess)) {
   1860       std::string prepend(dex_file_->PrettyMethod(dex_method_idx_));
   1861       prepend += " failed to verify: ";
   1862       PrependToLastFailMessage(prepend);
   1863       return false;
   1864     }
   1865     /* Clear "changed" and mark as visited. */
   1866     GetInstructionFlags(insn_idx).SetVisited();
   1867     GetInstructionFlags(insn_idx).ClearChanged();
   1868   }
   1869 
   1870   if (UNLIKELY(VLOG_IS_ON(verifier_debug))) {
   1871     /*
   1872      * Scan for dead code. There's nothing "evil" about dead code
   1873      * (besides the wasted space), but it indicates a flaw somewhere
   1874      * down the line, possibly in the verifier.
   1875      *
   1876      * If we've substituted "always throw" instructions into the stream,
   1877      * we are almost certainly going to have some dead code.
   1878      */
   1879     int dead_start = -1;
   1880 
   1881     for (const DexInstructionPcPair& inst : code_item_accessor_) {
   1882       const uint32_t insn_idx = inst.DexPc();
   1883       /*
   1884        * Switch-statement data doesn't get "visited" by scanner. It
   1885        * may or may not be preceded by a padding NOP (for alignment).
   1886        */
   1887       if (insns[insn_idx] == Instruction::kPackedSwitchSignature ||
   1888           insns[insn_idx] == Instruction::kSparseSwitchSignature ||
   1889           insns[insn_idx] == Instruction::kArrayDataSignature ||
   1890           (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) &&
   1891            (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature ||
   1892             insns[insn_idx + 1] == Instruction::kSparseSwitchSignature ||
   1893             insns[insn_idx + 1] == Instruction::kArrayDataSignature))) {
   1894         GetInstructionFlags(insn_idx).SetVisited();
   1895       }
   1896 
   1897       if (!GetInstructionFlags(insn_idx).IsVisited()) {
   1898         if (dead_start < 0) {
   1899           dead_start = insn_idx;
   1900         }
   1901       } else if (dead_start >= 0) {
   1902         LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
   1903                         << "-" << reinterpret_cast<void*>(insn_idx - 1);
   1904         dead_start = -1;
   1905       }
   1906     }
   1907     if (dead_start >= 0) {
   1908       LogVerifyInfo()
   1909           << "dead code " << reinterpret_cast<void*>(dead_start)
   1910           << "-" << reinterpret_cast<void*>(code_item_accessor_.InsnsSizeInCodeUnits() - 1);
   1911     }
   1912     // To dump the state of the verify after a method, do something like:
   1913     // if (dex_file_->PrettyMethod(dex_method_idx_) ==
   1914     //     "boolean java.lang.String.equals(java.lang.Object)") {
   1915     //   LOG(INFO) << info_messages_.str();
   1916     // }
   1917   }
   1918   return true;
   1919 }
   1920 
   1921 // Returns the index of the first final instance field of the given class, or kDexNoIndex if there
   1922 // is no such field.
   1923 static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, dex::TypeIndex type_idx) {
   1924   const DexFile::ClassDef* class_def = dex_file.FindClassDef(type_idx);
   1925   DCHECK(class_def != nullptr);
   1926   const uint8_t* class_data = dex_file.GetClassData(*class_def);
   1927   DCHECK(class_data != nullptr);
   1928   ClassDataItemIterator it(dex_file, class_data);
   1929   it.SkipStaticFields();
   1930   while (it.HasNextInstanceField()) {
   1931     if ((it.GetFieldAccessFlags() & kAccFinal) != 0) {
   1932       return it.GetMemberIndex();
   1933     }
   1934     it.Next();
   1935   }
   1936   return dex::kDexNoIndex;
   1937 }
   1938 
   1939 // Setup a register line for the given return instruction.
   1940 static void AdjustReturnLine(MethodVerifier* verifier,
   1941                              const Instruction* ret_inst,
   1942                              RegisterLine* line) {
   1943   Instruction::Code opcode = ret_inst->Opcode();
   1944 
   1945   switch (opcode) {
   1946     case Instruction::RETURN_VOID:
   1947     case Instruction::RETURN_VOID_NO_BARRIER:
   1948       SafelyMarkAllRegistersAsConflicts(verifier, line);
   1949       break;
   1950 
   1951     case Instruction::RETURN:
   1952     case Instruction::RETURN_OBJECT:
   1953       line->MarkAllRegistersAsConflictsExcept(verifier, ret_inst->VRegA_11x());
   1954       break;
   1955 
   1956     case Instruction::RETURN_WIDE:
   1957       line->MarkAllRegistersAsConflictsExceptWide(verifier, ret_inst->VRegA_11x());
   1958       break;
   1959 
   1960     default:
   1961       LOG(FATAL) << "Unknown return opcode " << opcode;
   1962       UNREACHABLE();
   1963   }
   1964 }
   1965 
   1966 bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
   1967   // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about.
   1968   // We want the state _before_ the instruction, for the case where the dex pc we're
   1969   // interested in is itself a monitor-enter instruction (which is a likely place
   1970   // for a thread to be suspended).
   1971   if (monitor_enter_dex_pcs_ != nullptr && work_insn_idx_ == interesting_dex_pc_) {
   1972     monitor_enter_dex_pcs_->clear();  // The new work line is more accurate than the previous one.
   1973 
   1974     std::map<uint32_t, DexLockInfo> depth_to_lock_info;
   1975     auto collector = [&](uint32_t dex_reg, uint32_t depth) {
   1976       auto insert_pair = depth_to_lock_info.emplace(depth, DexLockInfo(depth));
   1977       auto it = insert_pair.first;
   1978       auto set_insert_pair = it->second.dex_registers.insert(dex_reg);
   1979       DCHECK(set_insert_pair.second);
   1980     };
   1981     work_line_->IterateRegToLockDepths(collector);
   1982     for (auto& pair : depth_to_lock_info) {
   1983       monitor_enter_dex_pcs_->push_back(pair.second);
   1984       // Map depth to dex PC.
   1985       (*monitor_enter_dex_pcs_)[monitor_enter_dex_pcs_->size() - 1].dex_pc =
   1986           work_line_->GetMonitorEnterDexPc(pair.second.dex_pc);
   1987     }
   1988   }
   1989 
   1990   /*
   1991    * Once we finish decoding the instruction, we need to figure out where
   1992    * we can go from here. There are three possible ways to transfer
   1993    * control to another statement:
   1994    *
   1995    * (1) Continue to the next instruction. Applies to all but
   1996    *     unconditional branches, method returns, and exception throws.
   1997    * (2) Branch to one or more possible locations. Applies to branches
   1998    *     and switch statements.
   1999    * (3) Exception handlers. Applies to any instruction that can
   2000    *     throw an exception that is handled by an encompassing "try"
   2001    *     block.
   2002    *
   2003    * We can also return, in which case there is no successor instruction
   2004    * from this point.
   2005    *
   2006    * The behavior can be determined from the opcode flags.
   2007    */
   2008   const uint16_t* insns = code_item_accessor_.Insns() + work_insn_idx_;
   2009   const Instruction* inst = Instruction::At(insns);
   2010   int opcode_flags = Instruction::FlagsOf(inst->Opcode());
   2011 
   2012   int32_t branch_target = 0;
   2013   bool just_set_result = false;
   2014   if (UNLIKELY(VLOG_IS_ON(verifier_debug))) {
   2015     // Generate processing back trace to debug verifier
   2016     LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << "\n"
   2017                     << work_line_->Dump(this) << "\n";
   2018   }
   2019 
   2020   /*
   2021    * Make a copy of the previous register state. If the instruction
   2022    * can throw an exception, we will copy/merge this into the "catch"
   2023    * address rather than work_line, because we don't want the result
   2024    * from the "successful" code path (e.g. a check-cast that "improves"
   2025    * a type) to be visible to the exception handler.
   2026    */
   2027   if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) {
   2028     saved_line_->CopyFromLine(work_line_.get());
   2029   } else if (kIsDebugBuild) {
   2030     saved_line_->FillWithGarbage();
   2031   }
   2032   DCHECK(!have_pending_runtime_throw_failure_);  // Per-instruction flag, should not be set here.
   2033 
   2034 
   2035   // We need to ensure the work line is consistent while performing validation. When we spot a
   2036   // peephole pattern we compute a new line for either the fallthrough instruction or the
   2037   // branch target.
   2038   RegisterLineArenaUniquePtr branch_line;
   2039   RegisterLineArenaUniquePtr fallthrough_line;
   2040 
   2041   switch (inst->Opcode()) {
   2042     case Instruction::NOP:
   2043       /*
   2044        * A "pure" NOP has no effect on anything. Data tables start with
   2045        * a signature that looks like a NOP; if we see one of these in
   2046        * the course of executing code then we have a problem.
   2047        */
   2048       if (inst->VRegA_10x() != 0) {
   2049         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream";
   2050       }
   2051       break;
   2052 
   2053     case Instruction::MOVE:
   2054       work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr);
   2055       break;
   2056     case Instruction::MOVE_FROM16:
   2057       work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr);
   2058       break;
   2059     case Instruction::MOVE_16:
   2060       work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr);
   2061       break;
   2062     case Instruction::MOVE_WIDE:
   2063       work_line_->CopyRegister2(this, inst->VRegA_12x(), inst->VRegB_12x());
   2064       break;
   2065     case Instruction::MOVE_WIDE_FROM16:
   2066       work_line_->CopyRegister2(this, inst->VRegA_22x(), inst->VRegB_22x());
   2067       break;
   2068     case Instruction::MOVE_WIDE_16:
   2069       work_line_->CopyRegister2(this, inst->VRegA_32x(), inst->VRegB_32x());
   2070       break;
   2071     case Instruction::MOVE_OBJECT:
   2072       work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef);
   2073       break;
   2074     case Instruction::MOVE_OBJECT_FROM16:
   2075       work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef);
   2076       break;
   2077     case Instruction::MOVE_OBJECT_16:
   2078       work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef);
   2079       break;
   2080 
   2081     /*
   2082      * The move-result instructions copy data out of a "pseudo-register"
   2083      * with the results from the last method invocation. In practice we
   2084      * might want to hold the result in an actual CPU register, so the
   2085      * Dalvik spec requires that these only appear immediately after an
   2086      * invoke or filled-new-array.
   2087      *
   2088      * These calls invalidate the "result" register. (This is now
   2089      * redundant with the reset done below, but it can make the debug info
   2090      * easier to read in some cases.)
   2091      */
   2092     case Instruction::MOVE_RESULT:
   2093       work_line_->CopyResultRegister1(this, inst->VRegA_11x(), false);
   2094       break;
   2095     case Instruction::MOVE_RESULT_WIDE:
   2096       work_line_->CopyResultRegister2(this, inst->VRegA_11x());
   2097       break;
   2098     case Instruction::MOVE_RESULT_OBJECT:
   2099       work_line_->CopyResultRegister1(this, inst->VRegA_11x(), true);
   2100       break;
   2101 
   2102     case Instruction::MOVE_EXCEPTION: {
   2103       // We do not allow MOVE_EXCEPTION as the first instruction in a method. This is a simple case
   2104       // where one entrypoint to the catch block is not actually an exception path.
   2105       if (work_insn_idx_ == 0) {
   2106         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "move-exception at pc 0x0";
   2107         break;
   2108       }
   2109       /*
   2110        * This statement can only appear as the first instruction in an exception handler. We verify
   2111        * that as part of extracting the exception type from the catch block list.
   2112        */
   2113       const RegType& res_type = GetCaughtExceptionType();
   2114       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_11x(), res_type);
   2115       break;
   2116     }
   2117     case Instruction::RETURN_VOID:
   2118       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2119         if (!GetMethodReturnType().IsConflict()) {
   2120           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
   2121         }
   2122       }
   2123       break;
   2124     case Instruction::RETURN:
   2125       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2126         /* check the method signature */
   2127         const RegType& return_type = GetMethodReturnType();
   2128         if (!return_type.IsCategory1Types()) {
   2129           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type "
   2130                                             << return_type;
   2131         } else {
   2132           // Compilers may generate synthetic functions that write byte values into boolean fields.
   2133           // Also, it may use integer values for boolean, byte, short, and character return types.
   2134           const uint32_t vregA = inst->VRegA_11x();
   2135           const RegType& src_type = work_line_->GetRegisterType(this, vregA);
   2136           bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) ||
   2137                           ((return_type.IsBoolean() || return_type.IsByte() ||
   2138                            return_type.IsShort() || return_type.IsChar()) &&
   2139                            src_type.IsInteger()));
   2140           /* check the register contents */
   2141           bool success =
   2142               work_line_->VerifyRegisterType(this, vregA, use_src ? src_type : return_type);
   2143           if (!success) {
   2144             AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA));
   2145           }
   2146         }
   2147       }
   2148       break;
   2149     case Instruction::RETURN_WIDE:
   2150       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2151         /* check the method signature */
   2152         const RegType& return_type = GetMethodReturnType();
   2153         if (!return_type.IsCategory2Types()) {
   2154           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected";
   2155         } else {
   2156           /* check the register contents */
   2157           const uint32_t vregA = inst->VRegA_11x();
   2158           bool success = work_line_->VerifyRegisterType(this, vregA, return_type);
   2159           if (!success) {
   2160             AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA));
   2161           }
   2162         }
   2163       }
   2164       break;
   2165     case Instruction::RETURN_OBJECT:
   2166       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2167         const RegType& return_type = GetMethodReturnType();
   2168         if (!return_type.IsReferenceTypes()) {
   2169           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected";
   2170         } else {
   2171           /* return_type is the *expected* return type, not register value */
   2172           DCHECK(!return_type.IsZeroOrNull());
   2173           DCHECK(!return_type.IsUninitializedReference());
   2174           const uint32_t vregA = inst->VRegA_11x();
   2175           const RegType& reg_type = work_line_->GetRegisterType(this, vregA);
   2176           // Disallow returning undefined, conflict & uninitialized values and verify that the
   2177           // reference in vAA is an instance of the "return_type."
   2178           if (reg_type.IsUndefined()) {
   2179             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning undefined register";
   2180           } else if (reg_type.IsConflict()) {
   2181             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning register with conflict";
   2182           } else if (reg_type.IsUninitializedTypes()) {
   2183             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning uninitialized object '"
   2184                                               << reg_type << "'";
   2185           } else if (!reg_type.IsReferenceTypes()) {
   2186             // We really do expect a reference here.
   2187             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object returns a non-reference type "
   2188                                               << reg_type;
   2189           } else if (!return_type.IsAssignableFrom(reg_type, this)) {
   2190             if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) {
   2191               Fail(VERIFY_ERROR_NO_CLASS) << " can't resolve returned type '" << return_type
   2192                   << "' or '" << reg_type << "'";
   2193             } else {
   2194               bool soft_error = false;
   2195               // Check whether arrays are involved. They will show a valid class status, even
   2196               // if their components are erroneous.
   2197               if (reg_type.IsArrayTypes() && return_type.IsArrayTypes()) {
   2198                 return_type.CanAssignArray(reg_type, reg_types_, class_loader_, this, &soft_error);
   2199                 if (soft_error) {
   2200                   Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "array with erroneous component type: "
   2201                         << reg_type << " vs " << return_type;
   2202                 }
   2203               }
   2204 
   2205               if (!soft_error) {
   2206                 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
   2207                     << "', but expected from declaration '" << return_type << "'";
   2208               }
   2209             }
   2210           }
   2211         }
   2212       }
   2213       break;
   2214 
   2215       /* could be boolean, int, float, or a null reference */
   2216     case Instruction::CONST_4: {
   2217       int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
   2218       work_line_->SetRegisterType<LockOp::kClear>(
   2219           this, inst->VRegA_11n(), DetermineCat1Constant(val, need_precise_constants_));
   2220       break;
   2221     }
   2222     case Instruction::CONST_16: {
   2223       int16_t val = static_cast<int16_t>(inst->VRegB_21s());
   2224       work_line_->SetRegisterType<LockOp::kClear>(
   2225           this, inst->VRegA_21s(), DetermineCat1Constant(val, need_precise_constants_));
   2226       break;
   2227     }
   2228     case Instruction::CONST: {
   2229       int32_t val = inst->VRegB_31i();
   2230       work_line_->SetRegisterType<LockOp::kClear>(
   2231           this, inst->VRegA_31i(), DetermineCat1Constant(val, need_precise_constants_));
   2232       break;
   2233     }
   2234     case Instruction::CONST_HIGH16: {
   2235       int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
   2236       work_line_->SetRegisterType<LockOp::kClear>(
   2237           this, inst->VRegA_21h(), DetermineCat1Constant(val, need_precise_constants_));
   2238       break;
   2239     }
   2240       /* could be long or double; resolved upon use */
   2241     case Instruction::CONST_WIDE_16: {
   2242       int64_t val = static_cast<int16_t>(inst->VRegB_21s());
   2243       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2244       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2245       work_line_->SetRegisterTypeWide(this, inst->VRegA_21s(), lo, hi);
   2246       break;
   2247     }
   2248     case Instruction::CONST_WIDE_32: {
   2249       int64_t val = static_cast<int32_t>(inst->VRegB_31i());
   2250       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2251       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2252       work_line_->SetRegisterTypeWide(this, inst->VRegA_31i(), lo, hi);
   2253       break;
   2254     }
   2255     case Instruction::CONST_WIDE: {
   2256       int64_t val = inst->VRegB_51l();
   2257       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2258       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2259       work_line_->SetRegisterTypeWide(this, inst->VRegA_51l(), lo, hi);
   2260       break;
   2261     }
   2262     case Instruction::CONST_WIDE_HIGH16: {
   2263       int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48;
   2264       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2265       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2266       work_line_->SetRegisterTypeWide(this, inst->VRegA_21h(), lo, hi);
   2267       break;
   2268     }
   2269     case Instruction::CONST_STRING:
   2270       work_line_->SetRegisterType<LockOp::kClear>(
   2271           this, inst->VRegA_21c(), reg_types_.JavaLangString());
   2272       break;
   2273     case Instruction::CONST_STRING_JUMBO:
   2274       work_line_->SetRegisterType<LockOp::kClear>(
   2275           this, inst->VRegA_31c(), reg_types_.JavaLangString());
   2276       break;
   2277     case Instruction::CONST_CLASS: {
   2278       // Get type from instruction if unresolved then we need an access check
   2279       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   2280       const RegType& res_type = ResolveClass<CheckAccess::kYes>(dex::TypeIndex(inst->VRegB_21c()));
   2281       // Register holds class, ie its type is class, on error it will hold Conflict.
   2282       work_line_->SetRegisterType<LockOp::kClear>(
   2283           this, inst->VRegA_21c(), res_type.IsConflict() ? res_type
   2284                                                          : reg_types_.JavaLangClass());
   2285       break;
   2286     }
   2287     case Instruction::CONST_METHOD_HANDLE:
   2288       work_line_->SetRegisterType<LockOp::kClear>(
   2289           this, inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodHandle());
   2290       // TODO: add compiler support for const-method-{handle,type} (b/66890674)
   2291       Fail(VERIFY_ERROR_FORCE_INTERPRETER);
   2292       break;
   2293     case Instruction::CONST_METHOD_TYPE:
   2294       work_line_->SetRegisterType<LockOp::kClear>(
   2295           this, inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodType());
   2296       // TODO: add compiler support for const-method-{handle,type} (b/66890674)
   2297       Fail(VERIFY_ERROR_FORCE_INTERPRETER);
   2298       break;
   2299     case Instruction::MONITOR_ENTER:
   2300       work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_);
   2301       // Check whether the previous instruction is a move-object with vAA as a source, creating
   2302       // untracked lock aliasing.
   2303       if (0 != work_insn_idx_ && !GetInstructionFlags(work_insn_idx_).IsBranchTarget()) {
   2304         uint32_t prev_idx = work_insn_idx_ - 1;
   2305         while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) {
   2306           prev_idx--;
   2307         }
   2308         const Instruction& prev_inst = code_item_accessor_.InstructionAt(prev_idx);
   2309         switch (prev_inst.Opcode()) {
   2310           case Instruction::MOVE_OBJECT:
   2311           case Instruction::MOVE_OBJECT_16:
   2312           case Instruction::MOVE_OBJECT_FROM16:
   2313             if (prev_inst.VRegB() == inst->VRegA_11x()) {
   2314               // Redo the copy. This won't change the register types, but update the lock status
   2315               // for the aliased register.
   2316               work_line_->CopyRegister1(this,
   2317                                         prev_inst.VRegA(),
   2318                                         prev_inst.VRegB(),
   2319                                         kTypeCategoryRef);
   2320             }
   2321             break;
   2322 
   2323           default:  // Other instruction types ignored.
   2324             break;
   2325         }
   2326       }
   2327       break;
   2328     case Instruction::MONITOR_EXIT:
   2329       /*
   2330        * monitor-exit instructions are odd. They can throw exceptions,
   2331        * but when they do they act as if they succeeded and the PC is
   2332        * pointing to the following instruction. (This behavior goes back
   2333        * to the need to handle asynchronous exceptions, a now-deprecated
   2334        * feature that Dalvik doesn't support.)
   2335        *
   2336        * In practice we don't need to worry about this. The only
   2337        * exceptions that can be thrown from monitor-exit are for a
   2338        * null reference and -exit without a matching -enter. If the
   2339        * structured locking checks are working, the former would have
   2340        * failed on the -enter instruction, and the latter is impossible.
   2341        *
   2342        * This is fortunate, because issue 3221411 prevents us from
   2343        * chasing the "can throw" path when monitor verification is
   2344        * enabled. If we can fully verify the locking we can ignore
   2345        * some catch blocks (which will show up as "dead" code when
   2346        * we skip them here); if we can't, then the code path could be
   2347        * "live" so we still need to check it.
   2348        */
   2349       opcode_flags &= ~Instruction::kThrow;
   2350       work_line_->PopMonitor(this, inst->VRegA_11x());
   2351       break;
   2352     case Instruction::CHECK_CAST:
   2353     case Instruction::INSTANCE_OF: {
   2354       /*
   2355        * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This
   2356        * could be a "upcast" -- not expected, so we don't try to address it.)
   2357        *
   2358        * If it fails, an exception is thrown, which we deal with later by ignoring the update to
   2359        * dec_insn.vA when branching to a handler.
   2360        */
   2361       const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST);
   2362       const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c());
   2363       const RegType& res_type = ResolveClass<CheckAccess::kYes>(type_idx);
   2364       if (res_type.IsConflict()) {
   2365         // If this is a primitive type, fail HARD.
   2366         ObjPtr<mirror::Class> klass = Runtime::Current()->GetClassLinker()->LookupResolvedType(
   2367             type_idx, dex_cache_.Get(), class_loader_.Get());
   2368         if (klass != nullptr && klass->IsPrimitive()) {
   2369           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type "
   2370               << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in "
   2371               << GetDeclaringClass();
   2372           break;
   2373         }
   2374 
   2375         DCHECK_NE(failures_.size(), 0U);
   2376         if (!is_checkcast) {
   2377           work_line_->SetRegisterType<LockOp::kClear>(this,
   2378                                                       inst->VRegA_22c(),
   2379                                                       reg_types_.Boolean());
   2380         }
   2381         break;  // bad class
   2382       }
   2383       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   2384       uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c();
   2385       const RegType& orig_type = work_line_->GetRegisterType(this, orig_type_reg);
   2386       if (!res_type.IsNonZeroReferenceTypes()) {
   2387         if (is_checkcast) {
   2388           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type;
   2389         } else {
   2390           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type;
   2391         }
   2392       } else if (!orig_type.IsReferenceTypes()) {
   2393         if (is_checkcast) {
   2394           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg;
   2395         } else {
   2396           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg;
   2397         }
   2398       } else if (orig_type.IsUninitializedTypes()) {
   2399         if (is_checkcast) {
   2400           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on uninitialized reference in v"
   2401                                             << orig_type_reg;
   2402         } else {
   2403           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on uninitialized reference in v"
   2404                                             << orig_type_reg;
   2405         }
   2406       } else {
   2407         if (is_checkcast) {
   2408           work_line_->SetRegisterType<LockOp::kKeep>(this, inst->VRegA_21c(), res_type);
   2409         } else {
   2410           work_line_->SetRegisterType<LockOp::kClear>(this,
   2411                                                       inst->VRegA_22c(),
   2412                                                       reg_types_.Boolean());
   2413         }
   2414       }
   2415       break;
   2416     }
   2417     case Instruction::ARRAY_LENGTH: {
   2418       const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegB_12x());
   2419       if (res_type.IsReferenceTypes()) {
   2420         if (!res_type.IsArrayTypes() && !res_type.IsZeroOrNull()) {
   2421           // ie not an array or null
   2422           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
   2423         } else {
   2424           work_line_->SetRegisterType<LockOp::kClear>(this,
   2425                                                       inst->VRegA_12x(),
   2426                                                       reg_types_.Integer());
   2427         }
   2428       } else {
   2429         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
   2430       }
   2431       break;
   2432     }
   2433     case Instruction::NEW_INSTANCE: {
   2434       const RegType& res_type = ResolveClass<CheckAccess::kYes>(dex::TypeIndex(inst->VRegB_21c()));
   2435       if (res_type.IsConflict()) {
   2436         DCHECK_NE(failures_.size(), 0U);
   2437         break;  // bad class
   2438       }
   2439       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   2440       // can't create an instance of an interface or abstract class */
   2441       if (!res_type.IsInstantiableTypes()) {
   2442         Fail(VERIFY_ERROR_INSTANTIATION)
   2443             << "new-instance on primitive, interface or abstract class" << res_type;
   2444         // Soft failure so carry on to set register type.
   2445       }
   2446       const RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_);
   2447       // Any registers holding previous allocations from this address that have not yet been
   2448       // initialized must be marked invalid.
   2449       work_line_->MarkUninitRefsAsInvalid(this, uninit_type);
   2450       // add the new uninitialized reference to the register state
   2451       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_21c(), uninit_type);
   2452       break;
   2453     }
   2454     case Instruction::NEW_ARRAY:
   2455       VerifyNewArray(inst, false, false);
   2456       break;
   2457     case Instruction::FILLED_NEW_ARRAY:
   2458       VerifyNewArray(inst, true, false);
   2459       just_set_result = true;  // Filled new array sets result register
   2460       break;
   2461     case Instruction::FILLED_NEW_ARRAY_RANGE:
   2462       VerifyNewArray(inst, true, true);
   2463       just_set_result = true;  // Filled new array range sets result register
   2464       break;
   2465     case Instruction::CMPL_FLOAT:
   2466     case Instruction::CMPG_FLOAT:
   2467       if (!work_line_->VerifyRegisterType(this, inst->VRegB_23x(), reg_types_.Float())) {
   2468         break;
   2469       }
   2470       if (!work_line_->VerifyRegisterType(this, inst->VRegC_23x(), reg_types_.Float())) {
   2471         break;
   2472       }
   2473       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
   2474       break;
   2475     case Instruction::CMPL_DOUBLE:
   2476     case Instruction::CMPG_DOUBLE:
   2477       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.DoubleLo(),
   2478                                               reg_types_.DoubleHi())) {
   2479         break;
   2480       }
   2481       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.DoubleLo(),
   2482                                               reg_types_.DoubleHi())) {
   2483         break;
   2484       }
   2485       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
   2486       break;
   2487     case Instruction::CMP_LONG:
   2488       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.LongLo(),
   2489                                               reg_types_.LongHi())) {
   2490         break;
   2491       }
   2492       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.LongLo(),
   2493                                               reg_types_.LongHi())) {
   2494         break;
   2495       }
   2496       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
   2497       break;
   2498     case Instruction::THROW: {
   2499       const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x());
   2500       if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type, this)) {
   2501         if (res_type.IsUninitializedTypes()) {
   2502           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown exception not initialized";
   2503         } else if (!res_type.IsReferenceTypes()) {
   2504           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown value of non-reference type " << res_type;
   2505         } else {
   2506           Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT)
   2507                 << "thrown class " << res_type << " not instanceof Throwable";
   2508         }
   2509       }
   2510       break;
   2511     }
   2512     case Instruction::GOTO:
   2513     case Instruction::GOTO_16:
   2514     case Instruction::GOTO_32:
   2515       /* no effect on or use of registers */
   2516       break;
   2517 
   2518     case Instruction::PACKED_SWITCH:
   2519     case Instruction::SPARSE_SWITCH:
   2520       /* verify that vAA is an integer, or can be converted to one */
   2521       work_line_->VerifyRegisterType(this, inst->VRegA_31t(), reg_types_.Integer());
   2522       break;
   2523 
   2524     case Instruction::FILL_ARRAY_DATA: {
   2525       /* Similar to the verification done for APUT */
   2526       const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegA_31t());
   2527       /* array_type can be null if the reg type is Zero */
   2528       if (!array_type.IsZeroOrNull()) {
   2529         if (!array_type.IsArrayTypes()) {
   2530           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type "
   2531                                             << array_type;
   2532         } else if (array_type.IsUnresolvedTypes()) {
   2533           // If it's an unresolved array type, it must be non-primitive.
   2534           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data for array of type "
   2535                                             << array_type;
   2536         } else {
   2537           const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
   2538           DCHECK(!component_type.IsConflict());
   2539           if (component_type.IsNonZeroReferenceTypes()) {
   2540             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type "
   2541                                               << component_type;
   2542           } else {
   2543             // Now verify if the element width in the table matches the element width declared in
   2544             // the array
   2545             const uint16_t* array_data =
   2546                 insns + (insns[1] | (static_cast<int32_t>(insns[2]) << 16));
   2547             if (array_data[0] != Instruction::kArrayDataSignature) {
   2548               Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data";
   2549             } else {
   2550               size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
   2551               // Since we don't compress the data in Dex, expect to see equal width of data stored
   2552               // in the table and expected from the array class.
   2553               if (array_data[1] != elem_width) {
   2554                 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1]
   2555                                                   << " vs " << elem_width << ")";
   2556               }
   2557             }
   2558           }
   2559         }
   2560       }
   2561       break;
   2562     }
   2563     case Instruction::IF_EQ:
   2564     case Instruction::IF_NE: {
   2565       const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
   2566       const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
   2567       bool mismatch = false;
   2568       if (reg_type1.IsZeroOrNull()) {  // zero then integral or reference expected
   2569         mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes();
   2570       } else if (reg_type1.IsReferenceTypes()) {  // both references?
   2571         mismatch = !reg_type2.IsReferenceTypes();
   2572       } else {  // both integral?
   2573         mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes();
   2574       }
   2575       if (mismatch) {
   2576         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << ","
   2577                                           << reg_type2 << ") must both be references or integral";
   2578       }
   2579       break;
   2580     }
   2581     case Instruction::IF_LT:
   2582     case Instruction::IF_GE:
   2583     case Instruction::IF_GT:
   2584     case Instruction::IF_LE: {
   2585       const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
   2586       const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
   2587       if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) {
   2588         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << ","
   2589                                           << reg_type2 << ") must be integral";
   2590       }
   2591       break;
   2592     }
   2593     case Instruction::IF_EQZ:
   2594     case Instruction::IF_NEZ: {
   2595       const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
   2596       if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) {
   2597         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
   2598                                           << " unexpected as arg to if-eqz/if-nez";
   2599       }
   2600 
   2601       // Find previous instruction - its existence is a precondition to peephole optimization.
   2602       uint32_t instance_of_idx = 0;
   2603       if (0 != work_insn_idx_) {
   2604         instance_of_idx = work_insn_idx_ - 1;
   2605         while (0 != instance_of_idx && !GetInstructionFlags(instance_of_idx).IsOpcode()) {
   2606           instance_of_idx--;
   2607         }
   2608         if (FailOrAbort(GetInstructionFlags(instance_of_idx).IsOpcode(),
   2609                         "Unable to get previous instruction of if-eqz/if-nez for work index ",
   2610                         work_insn_idx_)) {
   2611           break;
   2612         }
   2613       } else {
   2614         break;
   2615       }
   2616 
   2617       const Instruction& instance_of_inst = code_item_accessor_.InstructionAt(instance_of_idx);
   2618 
   2619       /* Check for peep-hole pattern of:
   2620        *    ...;
   2621        *    instance-of vX, vY, T;
   2622        *    ifXXX vX, label ;
   2623        *    ...;
   2624        * label:
   2625        *    ...;
   2626        * and sharpen the type of vY to be type T.
   2627        * Note, this pattern can't be if:
   2628        *  - if there are other branches to this branch,
   2629        *  - when vX == vY.
   2630        */
   2631       if (!CurrentInsnFlags()->IsBranchTarget() &&
   2632           (Instruction::INSTANCE_OF == instance_of_inst.Opcode()) &&
   2633           (inst->VRegA_21t() == instance_of_inst.VRegA_22c()) &&
   2634           (instance_of_inst.VRegA_22c() != instance_of_inst.VRegB_22c())) {
   2635         // Check the type of the instance-of is different than that of registers type, as if they
   2636         // are the same there is no work to be done here. Check that the conversion is not to or
   2637         // from an unresolved type as type information is imprecise. If the instance-of is to an
   2638         // interface then ignore the type information as interfaces can only be treated as Objects
   2639         // and we don't want to disallow field and other operations on the object. If the value
   2640         // being instance-of checked against is known null (zero) then allow the optimization as
   2641         // we didn't have type information. If the merge of the instance-of type with the original
   2642         // type is assignable to the original then allow optimization. This check is performed to
   2643         // ensure that subsequent merges don't lose type information - such as becoming an
   2644         // interface from a class that would lose information relevant to field checks.
   2645         const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst.VRegB_22c());
   2646         const RegType& cast_type = ResolveClass<CheckAccess::kYes>(
   2647             dex::TypeIndex(instance_of_inst.VRegC_22c()));
   2648 
   2649         if (!orig_type.Equals(cast_type) &&
   2650             !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() &&
   2651             cast_type.HasClass() &&             // Could be conflict type, make sure it has a class.
   2652             !cast_type.GetClass()->IsInterface() &&
   2653             (orig_type.IsZeroOrNull() ||
   2654                 orig_type.IsStrictlyAssignableFrom(
   2655                     cast_type.Merge(orig_type, &reg_types_, this), this))) {
   2656           RegisterLine* update_line = RegisterLine::Create(code_item_accessor_.RegistersSize(),
   2657                                                            this);
   2658           if (inst->Opcode() == Instruction::IF_EQZ) {
   2659             fallthrough_line.reset(update_line);
   2660           } else {
   2661             branch_line.reset(update_line);
   2662           }
   2663           update_line->CopyFromLine(work_line_.get());
   2664           update_line->SetRegisterType<LockOp::kKeep>(this,
   2665                                                       instance_of_inst.VRegB_22c(),
   2666                                                       cast_type);
   2667           if (!GetInstructionFlags(instance_of_idx).IsBranchTarget() && 0 != instance_of_idx) {
   2668             // See if instance-of was preceded by a move-object operation, common due to the small
   2669             // register encoding space of instance-of, and propagate type information to the source
   2670             // of the move-object.
   2671             uint32_t move_idx = instance_of_idx - 1;
   2672             while (0 != move_idx && !GetInstructionFlags(move_idx).IsOpcode()) {
   2673               move_idx--;
   2674             }
   2675             if (FailOrAbort(GetInstructionFlags(move_idx).IsOpcode(),
   2676                             "Unable to get previous instruction of if-eqz/if-nez for work index ",
   2677                             work_insn_idx_)) {
   2678               break;
   2679             }
   2680             const Instruction& move_inst = code_item_accessor_.InstructionAt(move_idx);
   2681             switch (move_inst.Opcode()) {
   2682               case Instruction::MOVE_OBJECT:
   2683                 if (move_inst.VRegA_12x() == instance_of_inst.VRegB_22c()) {
   2684                   update_line->SetRegisterType<LockOp::kKeep>(this,
   2685                                                               move_inst.VRegB_12x(),
   2686                                                               cast_type);
   2687                 }
   2688                 break;
   2689               case Instruction::MOVE_OBJECT_FROM16:
   2690                 if (move_inst.VRegA_22x() == instance_of_inst.VRegB_22c()) {
   2691                   update_line->SetRegisterType<LockOp::kKeep>(this,
   2692                                                               move_inst.VRegB_22x(),
   2693                                                               cast_type);
   2694                 }
   2695                 break;
   2696               case Instruction::MOVE_OBJECT_16:
   2697                 if (move_inst.VRegA_32x() == instance_of_inst.VRegB_22c()) {
   2698                   update_line->SetRegisterType<LockOp::kKeep>(this,
   2699                                                               move_inst.VRegB_32x(),
   2700                                                               cast_type);
   2701                 }
   2702                 break;
   2703               default:
   2704                 break;
   2705             }
   2706           }
   2707         }
   2708       }
   2709 
   2710       break;
   2711     }
   2712     case Instruction::IF_LTZ:
   2713     case Instruction::IF_GEZ:
   2714     case Instruction::IF_GTZ:
   2715     case Instruction::IF_LEZ: {
   2716       const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
   2717       if (!reg_type.IsIntegralTypes()) {
   2718         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
   2719                                           << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez";
   2720       }
   2721       break;
   2722     }
   2723     case Instruction::AGET_BOOLEAN:
   2724       VerifyAGet(inst, reg_types_.Boolean(), true);
   2725       break;
   2726     case Instruction::AGET_BYTE:
   2727       VerifyAGet(inst, reg_types_.Byte(), true);
   2728       break;
   2729     case Instruction::AGET_CHAR:
   2730       VerifyAGet(inst, reg_types_.Char(), true);
   2731       break;
   2732     case Instruction::AGET_SHORT:
   2733       VerifyAGet(inst, reg_types_.Short(), true);
   2734       break;
   2735     case Instruction::AGET:
   2736       VerifyAGet(inst, reg_types_.Integer(), true);
   2737       break;
   2738     case Instruction::AGET_WIDE:
   2739       VerifyAGet(inst, reg_types_.LongLo(), true);
   2740       break;
   2741     case Instruction::AGET_OBJECT:
   2742       VerifyAGet(inst, reg_types_.JavaLangObject(false), false);
   2743       break;
   2744 
   2745     case Instruction::APUT_BOOLEAN:
   2746       VerifyAPut(inst, reg_types_.Boolean(), true);
   2747       break;
   2748     case Instruction::APUT_BYTE:
   2749       VerifyAPut(inst, reg_types_.Byte(), true);
   2750       break;
   2751     case Instruction::APUT_CHAR:
   2752       VerifyAPut(inst, reg_types_.Char(), true);
   2753       break;
   2754     case Instruction::APUT_SHORT:
   2755       VerifyAPut(inst, reg_types_.Short(), true);
   2756       break;
   2757     case Instruction::APUT:
   2758       VerifyAPut(inst, reg_types_.Integer(), true);
   2759       break;
   2760     case Instruction::APUT_WIDE:
   2761       VerifyAPut(inst, reg_types_.LongLo(), true);
   2762       break;
   2763     case Instruction::APUT_OBJECT:
   2764       VerifyAPut(inst, reg_types_.JavaLangObject(false), false);
   2765       break;
   2766 
   2767     case Instruction::IGET_BOOLEAN:
   2768     case Instruction::IGET_BOOLEAN_QUICK:
   2769       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, false);
   2770       break;
   2771     case Instruction::IGET_BYTE:
   2772     case Instruction::IGET_BYTE_QUICK:
   2773       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, false);
   2774       break;
   2775     case Instruction::IGET_CHAR:
   2776     case Instruction::IGET_CHAR_QUICK:
   2777       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, false);
   2778       break;
   2779     case Instruction::IGET_SHORT:
   2780     case Instruction::IGET_SHORT_QUICK:
   2781       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, false);
   2782       break;
   2783     case Instruction::IGET:
   2784     case Instruction::IGET_QUICK:
   2785       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, false);
   2786       break;
   2787     case Instruction::IGET_WIDE:
   2788     case Instruction::IGET_WIDE_QUICK:
   2789       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, false);
   2790       break;
   2791     case Instruction::IGET_OBJECT:
   2792     case Instruction::IGET_OBJECT_QUICK:
   2793       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false,
   2794                                                     false);
   2795       break;
   2796 
   2797     case Instruction::IPUT_BOOLEAN:
   2798     case Instruction::IPUT_BOOLEAN_QUICK:
   2799       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, false);
   2800       break;
   2801     case Instruction::IPUT_BYTE:
   2802     case Instruction::IPUT_BYTE_QUICK:
   2803       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, false);
   2804       break;
   2805     case Instruction::IPUT_CHAR:
   2806     case Instruction::IPUT_CHAR_QUICK:
   2807       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, false);
   2808       break;
   2809     case Instruction::IPUT_SHORT:
   2810     case Instruction::IPUT_SHORT_QUICK:
   2811       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, false);
   2812       break;
   2813     case Instruction::IPUT:
   2814     case Instruction::IPUT_QUICK:
   2815       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, false);
   2816       break;
   2817     case Instruction::IPUT_WIDE:
   2818     case Instruction::IPUT_WIDE_QUICK:
   2819       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, false);
   2820       break;
   2821     case Instruction::IPUT_OBJECT:
   2822     case Instruction::IPUT_OBJECT_QUICK:
   2823       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false,
   2824                                                     false);
   2825       break;
   2826 
   2827     case Instruction::SGET_BOOLEAN:
   2828       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, true);
   2829       break;
   2830     case Instruction::SGET_BYTE:
   2831       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, true);
   2832       break;
   2833     case Instruction::SGET_CHAR:
   2834       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, true);
   2835       break;
   2836     case Instruction::SGET_SHORT:
   2837       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, true);
   2838       break;
   2839     case Instruction::SGET:
   2840       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, true);
   2841       break;
   2842     case Instruction::SGET_WIDE:
   2843       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, true);
   2844       break;
   2845     case Instruction::SGET_OBJECT:
   2846       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false,
   2847                                                     true);
   2848       break;
   2849 
   2850     case Instruction::SPUT_BOOLEAN:
   2851       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, true);
   2852       break;
   2853     case Instruction::SPUT_BYTE:
   2854       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, true);
   2855       break;
   2856     case Instruction::SPUT_CHAR:
   2857       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, true);
   2858       break;
   2859     case Instruction::SPUT_SHORT:
   2860       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, true);
   2861       break;
   2862     case Instruction::SPUT:
   2863       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, true);
   2864       break;
   2865     case Instruction::SPUT_WIDE:
   2866       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, true);
   2867       break;
   2868     case Instruction::SPUT_OBJECT:
   2869       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false,
   2870                                                     true);
   2871       break;
   2872 
   2873     case Instruction::INVOKE_VIRTUAL:
   2874     case Instruction::INVOKE_VIRTUAL_RANGE:
   2875     case Instruction::INVOKE_SUPER:
   2876     case Instruction::INVOKE_SUPER_RANGE:
   2877     case Instruction::INVOKE_VIRTUAL_QUICK:
   2878     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
   2879       bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE ||
   2880                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE ||
   2881                        inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
   2882       bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
   2883                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
   2884       MethodType type = is_super ? METHOD_SUPER : METHOD_VIRTUAL;
   2885       ArtMethod* called_method = VerifyInvocationArgs(inst, type, is_range);
   2886       const RegType* return_type = nullptr;
   2887       if (called_method != nullptr) {
   2888         ObjPtr<mirror::Class> return_type_class = can_load_classes_
   2889             ? called_method->ResolveReturnType()
   2890             : called_method->LookupResolvedReturnType();
   2891         if (return_type_class != nullptr) {
   2892           return_type = &FromClass(called_method->GetReturnTypeDescriptor(),
   2893                                    return_type_class.Ptr(),
   2894                                    return_type_class->CannotBeAssignedFromOtherTypes());
   2895         } else {
   2896           DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   2897           self_->ClearException();
   2898         }
   2899       }
   2900       if (return_type == nullptr) {
   2901         uint32_t method_idx = GetMethodIdxOfInvoke(inst);
   2902         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2903         dex::TypeIndex return_type_idx =
   2904             dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2905         const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   2906         return_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   2907       }
   2908       if (!return_type->IsLowHalf()) {
   2909         work_line_->SetResultRegisterType(this, *return_type);
   2910       } else {
   2911         work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
   2912       }
   2913       just_set_result = true;
   2914       break;
   2915     }
   2916     case Instruction::INVOKE_DIRECT:
   2917     case Instruction::INVOKE_DIRECT_RANGE: {
   2918       bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
   2919       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT, is_range);
   2920       const char* return_type_descriptor;
   2921       bool is_constructor;
   2922       const RegType* return_type = nullptr;
   2923       if (called_method == nullptr) {
   2924         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2925         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2926         is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0;
   2927         dex::TypeIndex return_type_idx =
   2928             dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2929         return_type_descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
   2930       } else {
   2931         is_constructor = called_method->IsConstructor();
   2932         return_type_descriptor = called_method->GetReturnTypeDescriptor();
   2933         ObjPtr<mirror::Class> return_type_class = can_load_classes_
   2934             ? called_method->ResolveReturnType()
   2935             : called_method->LookupResolvedReturnType();
   2936         if (return_type_class != nullptr) {
   2937           return_type = &FromClass(return_type_descriptor,
   2938                                    return_type_class.Ptr(),
   2939                                    return_type_class->CannotBeAssignedFromOtherTypes());
   2940         } else {
   2941           DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   2942           self_->ClearException();
   2943         }
   2944       }
   2945       if (is_constructor) {
   2946         /*
   2947          * Some additional checks when calling a constructor. We know from the invocation arg check
   2948          * that the "this" argument is an instance of called_method->klass. Now we further restrict
   2949          * that to require that called_method->klass is the same as this->klass or this->super,
   2950          * allowing the latter only if the "this" argument is the same as the "this" argument to
   2951          * this method (which implies that we're in a constructor ourselves).
   2952          */
   2953         const RegType& this_type = work_line_->GetInvocationThis(this, inst);
   2954         if (this_type.IsConflict())  // failure.
   2955           break;
   2956 
   2957         /* no null refs allowed (?) */
   2958         if (this_type.IsZeroOrNull()) {
   2959           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref";
   2960           break;
   2961         }
   2962 
   2963         /* must be in same class or in superclass */
   2964         // const RegType& this_super_klass = this_type.GetSuperClass(&reg_types_);
   2965         // TODO: re-enable constructor type verification
   2966         // if (this_super_klass.IsConflict()) {
   2967           // Unknown super class, fail so we re-check at runtime.
   2968           // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'";
   2969           // break;
   2970         // }
   2971 
   2972         /* arg must be an uninitialized reference */
   2973         if (!this_type.IsUninitializedTypes()) {
   2974           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference "
   2975               << this_type;
   2976           break;
   2977         }
   2978 
   2979         /*
   2980          * Replace the uninitialized reference with an initialized one. We need to do this for all
   2981          * registers that have the same object instance in them, not just the "this" register.
   2982          */
   2983         work_line_->MarkRefsAsInitialized(this, this_type);
   2984       }
   2985       if (return_type == nullptr) {
   2986         return_type = &reg_types_.FromDescriptor(GetClassLoader(), return_type_descriptor, false);
   2987       }
   2988       if (!return_type->IsLowHalf()) {
   2989         work_line_->SetResultRegisterType(this, *return_type);
   2990       } else {
   2991         work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
   2992       }
   2993       just_set_result = true;
   2994       break;
   2995     }
   2996     case Instruction::INVOKE_STATIC:
   2997     case Instruction::INVOKE_STATIC_RANGE: {
   2998         bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
   2999         ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_STATIC, is_range);
   3000         const char* descriptor;
   3001         if (called_method == nullptr) {
   3002           uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3003           const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   3004           dex::TypeIndex return_type_idx =
   3005               dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   3006           descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   3007         } else {
   3008           descriptor = called_method->GetReturnTypeDescriptor();
   3009         }
   3010         const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3011         if (!return_type.IsLowHalf()) {
   3012           work_line_->SetResultRegisterType(this, return_type);
   3013         } else {
   3014           work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3015         }
   3016         just_set_result = true;
   3017       }
   3018       break;
   3019     case Instruction::INVOKE_INTERFACE:
   3020     case Instruction::INVOKE_INTERFACE_RANGE: {
   3021       bool is_range =  (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE);
   3022       ArtMethod* abs_method = VerifyInvocationArgs(inst, METHOD_INTERFACE, is_range);
   3023       if (abs_method != nullptr) {
   3024         mirror::Class* called_interface = abs_method->GetDeclaringClass();
   3025         if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) {
   3026           Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '"
   3027               << abs_method->PrettyMethod() << "'";
   3028           break;
   3029         }
   3030       }
   3031       /* Get the type of the "this" arg, which should either be a sub-interface of called
   3032        * interface or Object (see comments in RegType::JoinClass).
   3033        */
   3034       const RegType& this_type = work_line_->GetInvocationThis(this, inst);
   3035       if (this_type.IsZeroOrNull()) {
   3036         /* null pointer always passes (and always fails at runtime) */
   3037       } else {
   3038         if (this_type.IsUninitializedTypes()) {
   3039           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object "
   3040               << this_type;
   3041           break;
   3042         }
   3043         // In the past we have tried to assert that "called_interface" is assignable
   3044         // from "this_type.GetClass()", however, as we do an imprecise Join
   3045         // (RegType::JoinClass) we don't have full information on what interfaces are
   3046         // implemented by "this_type". For example, two classes may implement the same
   3047         // interfaces and have a common parent that doesn't implement the interface. The
   3048         // join will set "this_type" to the parent class and a test that this implements
   3049         // the interface will incorrectly fail.
   3050       }
   3051       /*
   3052        * We don't have an object instance, so we can't find the concrete method. However, all of
   3053        * the type information is in the abstract method, so we're good.
   3054        */
   3055       const char* descriptor;
   3056       if (abs_method == nullptr) {
   3057         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3058         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   3059         dex::TypeIndex return_type_idx =
   3060             dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   3061         descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   3062       } else {
   3063         descriptor = abs_method->GetReturnTypeDescriptor();
   3064       }
   3065       const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3066       if (!return_type.IsLowHalf()) {
   3067         work_line_->SetResultRegisterType(this, return_type);
   3068       } else {
   3069         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3070       }
   3071       just_set_result = true;
   3072       break;
   3073     }
   3074     case Instruction::INVOKE_POLYMORPHIC:
   3075     case Instruction::INVOKE_POLYMORPHIC_RANGE: {
   3076       bool is_range = (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE);
   3077       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_POLYMORPHIC, is_range);
   3078       if (called_method == nullptr) {
   3079         // Convert potential soft failures in VerifyInvocationArgs() to hard errors.
   3080         if (failure_messages_.size() > 0) {
   3081           std::string message = failure_messages_.back()->str();
   3082           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << message;
   3083         } else {
   3084           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-polymorphic verification failure.";
   3085         }
   3086         break;
   3087       }
   3088       if (!CheckSignaturePolymorphicMethod(called_method) ||
   3089           !CheckSignaturePolymorphicReceiver(inst)) {
   3090         DCHECK(HasFailures());
   3091         break;
   3092       }
   3093       const uint32_t proto_idx = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc();
   3094       const char* return_descriptor =
   3095           dex_file_->GetReturnTypeDescriptor(dex_file_->GetProtoId(proto_idx));
   3096       const RegType& return_type =
   3097           reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false);
   3098       if (!return_type.IsLowHalf()) {
   3099         work_line_->SetResultRegisterType(this, return_type);
   3100       } else {
   3101         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3102       }
   3103       just_set_result = true;
   3104       break;
   3105     }
   3106     case Instruction::INVOKE_CUSTOM:
   3107     case Instruction::INVOKE_CUSTOM_RANGE: {
   3108       // Verify registers based on method_type in the call site.
   3109       bool is_range = (inst->Opcode() == Instruction::INVOKE_CUSTOM_RANGE);
   3110 
   3111       // Step 1. Check the call site that produces the method handle for invocation
   3112       const uint32_t call_site_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
   3113       if (!CheckCallSite(call_site_idx)) {
   3114         DCHECK(HasFailures());
   3115         break;
   3116       }
   3117 
   3118       // Step 2. Check the register arguments correspond to the expected arguments for the
   3119       // method handle produced by step 1. The dex file verifier has checked ranges for
   3120       // the first three arguments and CheckCallSite has checked the method handle type.
   3121       CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx));
   3122       it.Next();  // Skip to name.
   3123       it.Next();  // Skip to method type of the method handle
   3124       const uint32_t proto_idx = static_cast<uint32_t>(it.GetJavaValue().i);
   3125       const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(proto_idx);
   3126       DexFileParameterIterator param_it(*dex_file_, proto_id);
   3127       // Treat method as static as it has yet to be determined.
   3128       VerifyInvocationArgsFromIterator(&param_it, inst, METHOD_STATIC, is_range, nullptr);
   3129       const char* return_descriptor = dex_file_->GetReturnTypeDescriptor(proto_id);
   3130 
   3131       // Step 3. Propagate return type information
   3132       const RegType& return_type =
   3133           reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false);
   3134       if (!return_type.IsLowHalf()) {
   3135         work_line_->SetResultRegisterType(this, return_type);
   3136       } else {
   3137         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3138       }
   3139       just_set_result = true;
   3140       // TODO: Add compiler support for invoke-custom (b/35337872).
   3141       Fail(VERIFY_ERROR_FORCE_INTERPRETER);
   3142       break;
   3143     }
   3144     case Instruction::NEG_INT:
   3145     case Instruction::NOT_INT:
   3146       work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer());
   3147       break;
   3148     case Instruction::NEG_LONG:
   3149     case Instruction::NOT_LONG:
   3150       work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3151                                    reg_types_.LongLo(), reg_types_.LongHi());
   3152       break;
   3153     case Instruction::NEG_FLOAT:
   3154       work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Float());
   3155       break;
   3156     case Instruction::NEG_DOUBLE:
   3157       work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3158                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3159       break;
   3160     case Instruction::INT_TO_LONG:
   3161       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3162                                      reg_types_.Integer());
   3163       break;
   3164     case Instruction::INT_TO_FLOAT:
   3165       work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Integer());
   3166       break;
   3167     case Instruction::INT_TO_DOUBLE:
   3168       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3169                                      reg_types_.Integer());
   3170       break;
   3171     case Instruction::LONG_TO_INT:
   3172       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(),
   3173                                        reg_types_.LongLo(), reg_types_.LongHi());
   3174       break;
   3175     case Instruction::LONG_TO_FLOAT:
   3176       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(),
   3177                                        reg_types_.LongLo(), reg_types_.LongHi());
   3178       break;
   3179     case Instruction::LONG_TO_DOUBLE:
   3180       work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3181                                    reg_types_.LongLo(), reg_types_.LongHi());
   3182       break;
   3183     case Instruction::FLOAT_TO_INT:
   3184       work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Float());
   3185       break;
   3186     case Instruction::FLOAT_TO_LONG:
   3187       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3188                                      reg_types_.Float());
   3189       break;
   3190     case Instruction::FLOAT_TO_DOUBLE:
   3191       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3192                                      reg_types_.Float());
   3193       break;
   3194     case Instruction::DOUBLE_TO_INT:
   3195       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(),
   3196                                        reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3197       break;
   3198     case Instruction::DOUBLE_TO_LONG:
   3199       work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3200                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3201       break;
   3202     case Instruction::DOUBLE_TO_FLOAT:
   3203       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(),
   3204                                        reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3205       break;
   3206     case Instruction::INT_TO_BYTE:
   3207       work_line_->CheckUnaryOp(this, inst, reg_types_.Byte(), reg_types_.Integer());
   3208       break;
   3209     case Instruction::INT_TO_CHAR:
   3210       work_line_->CheckUnaryOp(this, inst, reg_types_.Char(), reg_types_.Integer());
   3211       break;
   3212     case Instruction::INT_TO_SHORT:
   3213       work_line_->CheckUnaryOp(this, inst, reg_types_.Short(), reg_types_.Integer());
   3214       break;
   3215 
   3216     case Instruction::ADD_INT:
   3217     case Instruction::SUB_INT:
   3218     case Instruction::MUL_INT:
   3219     case Instruction::REM_INT:
   3220     case Instruction::DIV_INT:
   3221     case Instruction::SHL_INT:
   3222     case Instruction::SHR_INT:
   3223     case Instruction::USHR_INT:
   3224       work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3225                                 reg_types_.Integer(), false);
   3226       break;
   3227     case Instruction::AND_INT:
   3228     case Instruction::OR_INT:
   3229     case Instruction::XOR_INT:
   3230       work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3231                                 reg_types_.Integer(), true);
   3232       break;
   3233     case Instruction::ADD_LONG:
   3234     case Instruction::SUB_LONG:
   3235     case Instruction::MUL_LONG:
   3236     case Instruction::DIV_LONG:
   3237     case Instruction::REM_LONG:
   3238     case Instruction::AND_LONG:
   3239     case Instruction::OR_LONG:
   3240     case Instruction::XOR_LONG:
   3241       work_line_->CheckBinaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3242                                     reg_types_.LongLo(), reg_types_.LongHi(),
   3243                                     reg_types_.LongLo(), reg_types_.LongHi());
   3244       break;
   3245     case Instruction::SHL_LONG:
   3246     case Instruction::SHR_LONG:
   3247     case Instruction::USHR_LONG:
   3248       /* shift distance is Int, making these different from other binary operations */
   3249       work_line_->CheckBinaryOpWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3250                                          reg_types_.Integer());
   3251       break;
   3252     case Instruction::ADD_FLOAT:
   3253     case Instruction::SUB_FLOAT:
   3254     case Instruction::MUL_FLOAT:
   3255     case Instruction::DIV_FLOAT:
   3256     case Instruction::REM_FLOAT:
   3257       work_line_->CheckBinaryOp(this, inst, reg_types_.Float(), reg_types_.Float(),
   3258                                 reg_types_.Float(), false);
   3259       break;
   3260     case Instruction::ADD_DOUBLE:
   3261     case Instruction::SUB_DOUBLE:
   3262     case Instruction::MUL_DOUBLE:
   3263     case Instruction::DIV_DOUBLE:
   3264     case Instruction::REM_DOUBLE:
   3265       work_line_->CheckBinaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3266                                     reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3267                                     reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3268       break;
   3269     case Instruction::ADD_INT_2ADDR:
   3270     case Instruction::SUB_INT_2ADDR:
   3271     case Instruction::MUL_INT_2ADDR:
   3272     case Instruction::REM_INT_2ADDR:
   3273     case Instruction::SHL_INT_2ADDR:
   3274     case Instruction::SHR_INT_2ADDR:
   3275     case Instruction::USHR_INT_2ADDR:
   3276       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3277                                      reg_types_.Integer(), false);
   3278       break;
   3279     case Instruction::AND_INT_2ADDR:
   3280     case Instruction::OR_INT_2ADDR:
   3281     case Instruction::XOR_INT_2ADDR:
   3282       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3283                                      reg_types_.Integer(), true);
   3284       break;
   3285     case Instruction::DIV_INT_2ADDR:
   3286       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3287                                      reg_types_.Integer(), false);
   3288       break;
   3289     case Instruction::ADD_LONG_2ADDR:
   3290     case Instruction::SUB_LONG_2ADDR:
   3291     case Instruction::MUL_LONG_2ADDR:
   3292     case Instruction::DIV_LONG_2ADDR:
   3293     case Instruction::REM_LONG_2ADDR:
   3294     case Instruction::AND_LONG_2ADDR:
   3295     case Instruction::OR_LONG_2ADDR:
   3296     case Instruction::XOR_LONG_2ADDR:
   3297       work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3298                                          reg_types_.LongLo(), reg_types_.LongHi(),
   3299                                          reg_types_.LongLo(), reg_types_.LongHi());
   3300       break;
   3301     case Instruction::SHL_LONG_2ADDR:
   3302     case Instruction::SHR_LONG_2ADDR:
   3303     case Instruction::USHR_LONG_2ADDR:
   3304       work_line_->CheckBinaryOp2addrWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3305                                               reg_types_.Integer());
   3306       break;
   3307     case Instruction::ADD_FLOAT_2ADDR:
   3308     case Instruction::SUB_FLOAT_2ADDR:
   3309     case Instruction::MUL_FLOAT_2ADDR:
   3310     case Instruction::DIV_FLOAT_2ADDR:
   3311     case Instruction::REM_FLOAT_2ADDR:
   3312       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Float(), reg_types_.Float(),
   3313                                      reg_types_.Float(), false);
   3314       break;
   3315     case Instruction::ADD_DOUBLE_2ADDR:
   3316     case Instruction::SUB_DOUBLE_2ADDR:
   3317     case Instruction::MUL_DOUBLE_2ADDR:
   3318     case Instruction::DIV_DOUBLE_2ADDR:
   3319     case Instruction::REM_DOUBLE_2ADDR:
   3320       work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3321                                          reg_types_.DoubleLo(),  reg_types_.DoubleHi(),
   3322                                          reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3323       break;
   3324     case Instruction::ADD_INT_LIT16:
   3325     case Instruction::RSUB_INT_LIT16:
   3326     case Instruction::MUL_INT_LIT16:
   3327     case Instruction::DIV_INT_LIT16:
   3328     case Instruction::REM_INT_LIT16:
   3329       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false,
   3330                                  true);
   3331       break;
   3332     case Instruction::AND_INT_LIT16:
   3333     case Instruction::OR_INT_LIT16:
   3334     case Instruction::XOR_INT_LIT16:
   3335       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true,
   3336                                  true);
   3337       break;
   3338     case Instruction::ADD_INT_LIT8:
   3339     case Instruction::RSUB_INT_LIT8:
   3340     case Instruction::MUL_INT_LIT8:
   3341     case Instruction::DIV_INT_LIT8:
   3342     case Instruction::REM_INT_LIT8:
   3343     case Instruction::SHL_INT_LIT8:
   3344     case Instruction::SHR_INT_LIT8:
   3345     case Instruction::USHR_INT_LIT8:
   3346       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false,
   3347                                  false);
   3348       break;
   3349     case Instruction::AND_INT_LIT8:
   3350     case Instruction::OR_INT_LIT8:
   3351     case Instruction::XOR_INT_LIT8:
   3352       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true,
   3353                                  false);
   3354       break;
   3355 
   3356     // Special instructions.
   3357     case Instruction::RETURN_VOID_NO_BARRIER:
   3358       if (IsConstructor() && !IsStatic()) {
   3359         auto& declaring_class = GetDeclaringClass();
   3360         if (declaring_class.IsUnresolvedReference()) {
   3361           // We must iterate over the fields, even if we cannot use mirror classes to do so. Do it
   3362           // manually over the underlying dex file.
   3363           uint32_t first_index = GetFirstFinalInstanceFieldIndex(*dex_file_,
   3364               dex_file_->GetMethodId(dex_method_idx_).class_idx_);
   3365           if (first_index != dex::kDexNoIndex) {
   3366             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for field "
   3367                               << first_index;
   3368           }
   3369           break;
   3370         }
   3371         auto* klass = declaring_class.GetClass();
   3372         for (uint32_t i = 0, num_fields = klass->NumInstanceFields(); i < num_fields; ++i) {
   3373           if (klass->GetInstanceField(i)->IsFinal()) {
   3374             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for "
   3375                 << klass->GetInstanceField(i)->PrettyField();
   3376             break;
   3377           }
   3378         }
   3379       }
   3380       // Handle this like a RETURN_VOID now. Code is duplicated to separate standard from
   3381       // quickened opcodes (otherwise this could be a fall-through).
   3382       if (!IsConstructor()) {
   3383         if (!GetMethodReturnType().IsConflict()) {
   3384           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
   3385         }
   3386       }
   3387       break;
   3388 
   3389     /* These should never appear during verification. */
   3390     case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
   3391     case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
   3392     case Instruction::UNUSED_79:
   3393     case Instruction::UNUSED_7A:
   3394       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_);
   3395       break;
   3396 
   3397     /*
   3398      * DO NOT add a "default" clause here. Without it the compiler will
   3399      * complain if an instruction is missing (which is desirable).
   3400      */
   3401   }  // end - switch (dec_insn.opcode)
   3402 
   3403   if (have_pending_hard_failure_) {
   3404     if (Runtime::Current()->IsAotCompiler()) {
   3405       /* When AOT compiling, check that the last failure is a hard failure */
   3406       if (failures_[failures_.size() - 1] != VERIFY_ERROR_BAD_CLASS_HARD) {
   3407         LOG(ERROR) << "Pending failures:";
   3408         for (auto& error : failures_) {
   3409           LOG(ERROR) << error;
   3410         }
   3411         for (auto& error_msg : failure_messages_) {
   3412           LOG(ERROR) << error_msg->str();
   3413         }
   3414         LOG(FATAL) << "Pending hard failure, but last failure not hard.";
   3415       }
   3416     }
   3417     /* immediate failure, reject class */
   3418     info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_);
   3419     return false;
   3420   } else if (have_pending_runtime_throw_failure_) {
   3421     /* checking interpreter will throw, mark following code as unreachable */
   3422     opcode_flags = Instruction::kThrow;
   3423     // Note: the flag must be reset as it is only global to decouple Fail and is semantically per
   3424     //       instruction. However, RETURN checking may throw LOCKING errors, so we clear at the
   3425     //       very end.
   3426   }
   3427   /*
   3428    * If we didn't just set the result register, clear it out. This ensures that you can only use
   3429    * "move-result" immediately after the result is set. (We could check this statically, but it's
   3430    * not expensive and it makes our debugging output cleaner.)
   3431    */
   3432   if (!just_set_result) {
   3433     work_line_->SetResultTypeToUnknown(this);
   3434   }
   3435 
   3436   /*
   3437    * Handle "branch". Tag the branch target.
   3438    *
   3439    * NOTE: instructions like Instruction::EQZ provide information about the
   3440    * state of the register when the branch is taken or not taken. For example,
   3441    * somebody could get a reference field, check it for zero, and if the
   3442    * branch is taken immediately store that register in a boolean field
   3443    * since the value is known to be zero. We do not currently account for
   3444    * that, and will reject the code.
   3445    *
   3446    * TODO: avoid re-fetching the branch target
   3447    */
   3448   if ((opcode_flags & Instruction::kBranch) != 0) {
   3449     bool isConditional, selfOkay;
   3450     if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) {
   3451       /* should never happen after static verification */
   3452       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch";
   3453       return false;
   3454     }
   3455     DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0);
   3456     if (!CheckNotMoveExceptionOrMoveResult(code_item_accessor_.Insns(),
   3457                                            work_insn_idx_ + branch_target)) {
   3458       return false;
   3459     }
   3460     /* update branch target, set "changed" if appropriate */
   3461     if (nullptr != branch_line) {
   3462       if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) {
   3463         return false;
   3464       }
   3465     } else {
   3466       if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) {
   3467         return false;
   3468       }
   3469     }
   3470   }
   3471 
   3472   /*
   3473    * Handle "switch". Tag all possible branch targets.
   3474    *
   3475    * We've already verified that the table is structurally sound, so we
   3476    * just need to walk through and tag the targets.
   3477    */
   3478   if ((opcode_flags & Instruction::kSwitch) != 0) {
   3479     int offset_to_switch = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
   3480     const uint16_t* switch_insns = insns + offset_to_switch;
   3481     int switch_count = switch_insns[1];
   3482     int offset_to_targets, targ;
   3483 
   3484     if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
   3485       /* 0 = sig, 1 = count, 2/3 = first key */
   3486       offset_to_targets = 4;
   3487     } else {
   3488       /* 0 = sig, 1 = count, 2..count * 2 = keys */
   3489       DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH);
   3490       offset_to_targets = 2 + 2 * switch_count;
   3491     }
   3492 
   3493     /* verify each switch target */
   3494     for (targ = 0; targ < switch_count; targ++) {
   3495       int offset;
   3496       uint32_t abs_offset;
   3497 
   3498       /* offsets are 32-bit, and only partly endian-swapped */
   3499       offset = switch_insns[offset_to_targets + targ * 2] |
   3500          (static_cast<int32_t>(switch_insns[offset_to_targets + targ * 2 + 1]) << 16);
   3501       abs_offset = work_insn_idx_ + offset;
   3502       DCHECK_LT(abs_offset, code_item_accessor_.InsnsSizeInCodeUnits());
   3503       if (!CheckNotMoveExceptionOrMoveResult(code_item_accessor_.Insns(), abs_offset)) {
   3504         return false;
   3505       }
   3506       if (!UpdateRegisters(abs_offset, work_line_.get(), false)) {
   3507         return false;
   3508       }
   3509     }
   3510   }
   3511 
   3512   /*
   3513    * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a
   3514    * "try" block when they throw, control transfers out of the method.)
   3515    */
   3516   if ((opcode_flags & Instruction::kThrow) != 0 && GetInstructionFlags(work_insn_idx_).IsInTry()) {
   3517     bool has_catch_all_handler = false;
   3518     const DexFile::TryItem* try_item = code_item_accessor_.FindTryItem(work_insn_idx_);
   3519     CHECK(try_item != nullptr);
   3520     CatchHandlerIterator iterator(code_item_accessor_, *try_item);
   3521 
   3522     // Need the linker to try and resolve the handled class to check if it's Throwable.
   3523     ClassLinker* linker = Runtime::Current()->GetClassLinker();
   3524 
   3525     for (; iterator.HasNext(); iterator.Next()) {
   3526       dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex();
   3527       if (!handler_type_idx.IsValid()) {
   3528         has_catch_all_handler = true;
   3529       } else {
   3530         // It is also a catch-all if it is java.lang.Throwable.
   3531         ObjPtr<mirror::Class> klass =
   3532             linker->ResolveType(handler_type_idx, dex_cache_, class_loader_);
   3533         if (klass != nullptr) {
   3534           if (klass == mirror::Throwable::GetJavaLangThrowable()) {
   3535             has_catch_all_handler = true;
   3536           }
   3537         } else {
   3538           // Clear exception.
   3539           DCHECK(self_->IsExceptionPending());
   3540           self_->ClearException();
   3541         }
   3542       }
   3543       /*
   3544        * Merge registers into the "catch" block. We want to use the "savedRegs" rather than
   3545        * "work_regs", because at runtime the exception will be thrown before the instruction
   3546        * modifies any registers.
   3547        */
   3548       if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) {
   3549         return false;
   3550       }
   3551     }
   3552 
   3553     /*
   3554      * If the monitor stack depth is nonzero, there must be a "catch all" handler for this
   3555      * instruction. This does apply to monitor-exit because of async exception handling.
   3556      */
   3557     if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) {
   3558       /*
   3559        * The state in work_line reflects the post-execution state. If the current instruction is a
   3560        * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws,
   3561        * it will do so before grabbing the lock).
   3562        */
   3563       if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) {
   3564         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   3565             << "expected to be within a catch-all for an instruction where a monitor is held";
   3566         return false;
   3567       }
   3568     }
   3569   }
   3570 
   3571   /* Handle "continue". Tag the next consecutive instruction.
   3572    *  Note: Keep the code handling "continue" case below the "branch" and "switch" cases,
   3573    *        because it changes work_line_ when performing peephole optimization
   3574    *        and this change should not be used in those cases.
   3575    */
   3576   if ((opcode_flags & Instruction::kContinue) != 0) {
   3577     DCHECK_EQ(&code_item_accessor_.InstructionAt(work_insn_idx_), inst);
   3578     uint32_t next_insn_idx = work_insn_idx_ + inst->SizeInCodeUnits();
   3579     if (next_insn_idx >= code_item_accessor_.InsnsSizeInCodeUnits()) {
   3580       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area";
   3581       return false;
   3582     }
   3583     // The only way to get to a move-exception instruction is to get thrown there. Make sure the
   3584     // next instruction isn't one.
   3585     if (!CheckNotMoveException(code_item_accessor_.Insns(), next_insn_idx)) {
   3586       return false;
   3587     }
   3588     if (nullptr != fallthrough_line) {
   3589       // Make workline consistent with fallthrough computed from peephole optimization.
   3590       work_line_->CopyFromLine(fallthrough_line.get());
   3591     }
   3592     if (GetInstructionFlags(next_insn_idx).IsReturn()) {
   3593       // For returns we only care about the operand to the return, all other registers are dead.
   3594       const Instruction* ret_inst = &code_item_accessor_.InstructionAt(next_insn_idx);
   3595       AdjustReturnLine(this, ret_inst, work_line_.get());
   3596     }
   3597     RegisterLine* next_line = reg_table_.GetLine(next_insn_idx);
   3598     if (next_line != nullptr) {
   3599       // Merge registers into what we have for the next instruction, and set the "changed" flag if
   3600       // needed. If the merge changes the state of the registers then the work line will be
   3601       // updated.
   3602       if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) {
   3603         return false;
   3604       }
   3605     } else {
   3606       /*
   3607        * We're not recording register data for the next instruction, so we don't know what the
   3608        * prior state was. We have to assume that something has changed and re-evaluate it.
   3609        */
   3610       GetInstructionFlags(next_insn_idx).SetChanged();
   3611     }
   3612   }
   3613 
   3614   /* If we're returning from the method, make sure monitor stack is empty. */
   3615   if ((opcode_flags & Instruction::kReturn) != 0) {
   3616     work_line_->VerifyMonitorStackEmpty(this);
   3617   }
   3618 
   3619   /*
   3620    * Update start_guess. Advance to the next instruction of that's
   3621    * possible, otherwise use the branch target if one was found. If
   3622    * neither of those exists we're in a return or throw; leave start_guess
   3623    * alone and let the caller sort it out.
   3624    */
   3625   if ((opcode_flags & Instruction::kContinue) != 0) {
   3626     DCHECK_EQ(&code_item_accessor_.InstructionAt(work_insn_idx_), inst);
   3627     *start_guess = work_insn_idx_ + inst->SizeInCodeUnits();
   3628   } else if ((opcode_flags & Instruction::kBranch) != 0) {
   3629     /* we're still okay if branch_target is zero */
   3630     *start_guess = work_insn_idx_ + branch_target;
   3631   }
   3632 
   3633   DCHECK_LT(*start_guess, code_item_accessor_.InsnsSizeInCodeUnits());
   3634   DCHECK(GetInstructionFlags(*start_guess).IsOpcode());
   3635 
   3636   if (have_pending_runtime_throw_failure_) {
   3637     have_any_pending_runtime_throw_failure_ = true;
   3638     // Reset the pending_runtime_throw flag now.
   3639     have_pending_runtime_throw_failure_ = false;
   3640   }
   3641 
   3642   return true;
   3643 }  // NOLINT(readability/fn_size)
   3644 
   3645 void MethodVerifier::UninstantiableError(const char* descriptor) {
   3646   Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for "
   3647                                            << "non-instantiable klass " << descriptor;
   3648 }
   3649 
   3650 inline bool MethodVerifier::IsInstantiableOrPrimitive(ObjPtr<mirror::Class> klass) {
   3651   return klass->IsInstantiable() || klass->IsPrimitive();
   3652 }
   3653 
   3654 template <MethodVerifier::CheckAccess C>
   3655 const RegType& MethodVerifier::ResolveClass(dex::TypeIndex class_idx) {
   3656   ClassLinker* linker = Runtime::Current()->GetClassLinker();
   3657   ObjPtr<mirror::Class> klass = can_load_classes_
   3658       ? linker->ResolveType(class_idx, dex_cache_, class_loader_)
   3659       : linker->LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get());
   3660   if (can_load_classes_ && klass == nullptr) {
   3661     DCHECK(self_->IsExceptionPending());
   3662     self_->ClearException();
   3663   }
   3664   const RegType* result = nullptr;
   3665   if (klass != nullptr) {
   3666     bool precise = klass->CannotBeAssignedFromOtherTypes();
   3667     if (precise && !IsInstantiableOrPrimitive(klass)) {
   3668       const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3669       UninstantiableError(descriptor);
   3670       precise = false;
   3671     }
   3672     result = reg_types_.FindClass(klass.Ptr(), precise);
   3673     if (result == nullptr) {
   3674       const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3675       result = reg_types_.InsertClass(descriptor, klass.Ptr(), precise);
   3676     }
   3677   } else {
   3678     const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3679     result = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3680   }
   3681   DCHECK(result != nullptr);
   3682   if (result->IsConflict()) {
   3683     const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3684     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor
   3685         << "' in " << GetDeclaringClass();
   3686     return *result;
   3687   }
   3688 
   3689   // Record result of class resolution attempt.
   3690   VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass.Ptr());
   3691 
   3692   // If requested, check if access is allowed. Unresolved types are included in this check, as the
   3693   // interpreter only tests whether access is allowed when a class is not pre-verified and runs in
   3694   // the access-checks interpreter. If result is primitive, skip the access check.
   3695   //
   3696   // Note: we do this for unresolved classes to trigger re-verification at runtime.
   3697   if (C == CheckAccess::kYes && result->IsNonZeroReferenceTypes()) {
   3698     const RegType& referrer = GetDeclaringClass();
   3699     if (!referrer.CanAccess(*result)) {
   3700       Fail(VERIFY_ERROR_ACCESS_CLASS) << "(possibly) illegal class access: '"
   3701                                       << referrer << "' -> '" << *result << "'";
   3702     }
   3703   }
   3704   return *result;
   3705 }
   3706 
   3707 // Instantiate ResolveClass variants. This is required as the -inl file has a function with a call
   3708 // to ResolveClass, and compilers may decide to inline, requiring a symbol.
   3709 template const RegType& MethodVerifier::ResolveClass<MethodVerifier::CheckAccess::kNo>(
   3710     dex::TypeIndex class_idx);
   3711 template const RegType& MethodVerifier::ResolveClass<MethodVerifier::CheckAccess::kYes>(
   3712     dex::TypeIndex class_idx);
   3713 
   3714 const RegType& MethodVerifier::GetCaughtExceptionType() {
   3715   const RegType* common_super = nullptr;
   3716   if (code_item_accessor_.TriesSize() != 0) {
   3717     const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
   3718     uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
   3719     for (uint32_t i = 0; i < handlers_size; i++) {
   3720       CatchHandlerIterator iterator(handlers_ptr);
   3721       for (; iterator.HasNext(); iterator.Next()) {
   3722         if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) {
   3723           if (!iterator.GetHandlerTypeIndex().IsValid()) {
   3724             common_super = &reg_types_.JavaLangThrowable(false);
   3725           } else {
   3726             const RegType& exception =
   3727                 ResolveClass<CheckAccess::kYes>(iterator.GetHandlerTypeIndex());
   3728             if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception, this)) {
   3729               DCHECK(!exception.IsUninitializedTypes());  // Comes from dex, shouldn't be uninit.
   3730               if (exception.IsUnresolvedTypes()) {
   3731                 // We don't know enough about the type. Fail here and let runtime handle it.
   3732                 Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception;
   3733                 return exception;
   3734               } else {
   3735                 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception;
   3736                 return reg_types_.Conflict();
   3737               }
   3738             } else if (common_super == nullptr) {
   3739               common_super = &exception;
   3740             } else if (common_super->Equals(exception)) {
   3741               // odd case, but nothing to do
   3742             } else {
   3743               common_super = &common_super->Merge(exception, &reg_types_, this);
   3744               if (FailOrAbort(reg_types_.JavaLangThrowable(false).IsAssignableFrom(
   3745                                   *common_super, this),
   3746                               "java.lang.Throwable is not assignable-from common_super at ",
   3747                               work_insn_idx_)) {
   3748                 break;
   3749               }
   3750             }
   3751           }
   3752         }
   3753       }
   3754       handlers_ptr = iterator.EndDataPointer();
   3755     }
   3756   }
   3757   if (common_super == nullptr) {
   3758     /* no catch blocks, or no catches with classes we can find */
   3759     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unable to find exception handler";
   3760     return reg_types_.Conflict();
   3761   }
   3762   return *common_super;
   3763 }
   3764 
   3765 ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(
   3766     uint32_t dex_method_idx, MethodType method_type) {
   3767   const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
   3768   const RegType& klass_type = ResolveClass<CheckAccess::kYes>(method_id.class_idx_);
   3769   if (klass_type.IsConflict()) {
   3770     std::string append(" in attempt to access method ");
   3771     append += dex_file_->GetMethodName(method_id);
   3772     AppendToLastFailMessage(append);
   3773     return nullptr;
   3774   }
   3775   if (klass_type.IsUnresolvedTypes()) {
   3776     return nullptr;  // Can't resolve Class so no more to do here
   3777   }
   3778   ObjPtr<mirror::Class> klass = klass_type.GetClass();
   3779   const RegType& referrer = GetDeclaringClass();
   3780   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   3781   PointerSize pointer_size = class_linker->GetImagePointerSize();
   3782 
   3783   ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx, pointer_size);
   3784   if (res_method == nullptr) {
   3785     res_method = class_linker->FindResolvedMethod(
   3786         klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx);
   3787   }
   3788 
   3789   // Record result of method resolution attempt. The klass resolution has recorded whether
   3790   // the class is an interface or not and therefore the type of the lookup performed above.
   3791   // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
   3792   VerifierDeps::MaybeRecordMethodResolution(*dex_file_, dex_method_idx, res_method);
   3793 
   3794   bool must_fail = false;
   3795   // This is traditional and helps with screwy bytecode. It will tell you that, yes, a method
   3796   // exists, but that it's called incorrectly. This significantly helps debugging, as locally it's
   3797   // hard to see the differences.
   3798   // If we don't have res_method here we must fail. Just use this bool to make sure of that with a
   3799   // DCHECK.
   3800   if (res_method == nullptr) {
   3801     must_fail = true;
   3802     // Try to find the method also with the other type for better error reporting below
   3803     // but do not store such bogus lookup result in the DexCache or VerifierDeps.
   3804     res_method = class_linker->FindIncompatibleMethod(
   3805         klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx);
   3806   }
   3807 
   3808   if (res_method == nullptr) {
   3809     Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method "
   3810                                  << klass->PrettyDescriptor() << "."
   3811                                  << dex_file_->GetMethodName(method_id) << " "
   3812                                  << dex_file_->GetMethodSignature(method_id);
   3813     return nullptr;
   3814   }
   3815 
   3816   // Make sure calls to constructors are "direct". There are additional restrictions but we don't
   3817   // enforce them here.
   3818   if (res_method->IsConstructor() && method_type != METHOD_DIRECT) {
   3819     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor "
   3820                                       << res_method->PrettyMethod();
   3821     return nullptr;
   3822   }
   3823   // Disallow any calls to class initializers.
   3824   if (res_method->IsClassInitializer()) {
   3825     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer "
   3826                                       << res_method->PrettyMethod();
   3827     return nullptr;
   3828   }
   3829 
   3830   // Check that interface methods are static or match interface classes.
   3831   // We only allow statics if we don't have default methods enabled.
   3832   //
   3833   // Note: this check must be after the initializer check, as those are required to fail a class,
   3834   //       while this check implies an IncompatibleClassChangeError.
   3835   if (klass->IsInterface()) {
   3836     // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if
   3837     // default methods are supported for the dex file), or invoke-static.
   3838     if (method_type != METHOD_INTERFACE &&
   3839         method_type != METHOD_STATIC &&
   3840         (!dex_file_->SupportsDefaultMethods() ||
   3841          method_type != METHOD_DIRECT) &&
   3842         method_type != METHOD_SUPER) {
   3843       Fail(VERIFY_ERROR_CLASS_CHANGE)
   3844           << "non-interface method " << dex_file_->PrettyMethod(dex_method_idx)
   3845           << " is in an interface class " << klass->PrettyClass();
   3846       return nullptr;
   3847     }
   3848   } else {
   3849     if (method_type == METHOD_INTERFACE) {
   3850       Fail(VERIFY_ERROR_CLASS_CHANGE)
   3851           << "interface method " << dex_file_->PrettyMethod(dex_method_idx)
   3852           << " is in a non-interface class " << klass->PrettyClass();
   3853       return nullptr;
   3854     }
   3855   }
   3856 
   3857   // Check specifically for non-public object methods being provided for interface dispatch. This
   3858   // can occur if we failed to find a method with FindInterfaceMethod but later find one with
   3859   // FindClassMethod for error message use.
   3860   if (method_type == METHOD_INTERFACE &&
   3861       res_method->GetDeclaringClass()->IsObjectClass() &&
   3862       !res_method->IsPublic()) {
   3863     Fail(VERIFY_ERROR_NO_METHOD) << "invoke-interface " << klass->PrettyDescriptor() << "."
   3864                                  << dex_file_->GetMethodName(method_id) << " "
   3865                                  << dex_file_->GetMethodSignature(method_id) << " resolved to "
   3866                                  << "non-public object method " << res_method->PrettyMethod() << " "
   3867                                  << "but non-public Object methods are excluded from interface "
   3868                                  << "method resolution.";
   3869     return nullptr;
   3870   }
   3871   // Check if access is allowed.
   3872   if (!referrer.CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
   3873     Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call "
   3874                                      << res_method->PrettyMethod()
   3875                                      << " from " << referrer << ")";
   3876     return res_method;
   3877   }
   3878   // Check that invoke-virtual and invoke-super are not used on private methods of the same class.
   3879   if (res_method->IsPrivate() && (method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER)) {
   3880     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method "
   3881                                       << res_method->PrettyMethod();
   3882     return nullptr;
   3883   }
   3884   // See if the method type implied by the invoke instruction matches the access flags for the
   3885   // target method. The flags for METHOD_POLYMORPHIC are based on there being precisely two
   3886   // signature polymorphic methods supported by the run-time which are native methods with variable
   3887   // arguments.
   3888   if ((method_type == METHOD_DIRECT && (!res_method->IsDirect() || res_method->IsStatic())) ||
   3889       (method_type == METHOD_STATIC && !res_method->IsStatic()) ||
   3890       ((method_type == METHOD_SUPER ||
   3891         method_type == METHOD_VIRTUAL ||
   3892         method_type == METHOD_INTERFACE) && res_method->IsDirect()) ||
   3893       ((method_type == METHOD_POLYMORPHIC) &&
   3894        (!res_method->IsNative() || !res_method->IsVarargs()))) {
   3895     Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method "
   3896                                        "type of " << res_method->PrettyMethod();
   3897     return nullptr;
   3898   }
   3899   // Make sure we weren't expecting to fail.
   3900   DCHECK(!must_fail) << "invoke type (" << method_type << ")"
   3901                      << klass->PrettyDescriptor() << "."
   3902                      << dex_file_->GetMethodName(method_id) << " "
   3903                      << dex_file_->GetMethodSignature(method_id) << " unexpectedly resolved to "
   3904                      << res_method->PrettyMethod() << " without error. Initially this method was "
   3905                      << "not found so we were expecting to fail for some reason.";
   3906   return res_method;
   3907 }
   3908 
   3909 template <class T>
   3910 ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(
   3911     T* it, const Instruction* inst, MethodType method_type, bool is_range, ArtMethod* res_method) {
   3912   // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
   3913   // match the call to the signature. Also, we might be calling through an abstract method
   3914   // definition (which doesn't have register count values).
   3915   const size_t expected_args = inst->VRegA();
   3916   /* caught by static verifier */
   3917   DCHECK(is_range || expected_args <= 5);
   3918 
   3919   if (expected_args > code_item_accessor_.OutsSize()) {
   3920     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
   3921                                       << ") exceeds outsSize ("
   3922                                       << code_item_accessor_.OutsSize() << ")";
   3923     return nullptr;
   3924   }
   3925 
   3926   /*
   3927    * Check the "this" argument, which must be an instance of the class that declared the method.
   3928    * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
   3929    * rigorous check here (which is okay since we have to do it at runtime).
   3930    */
   3931   if (method_type != METHOD_STATIC) {
   3932     const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst);
   3933     if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
   3934       CHECK(have_pending_hard_failure_);
   3935       return nullptr;
   3936     }
   3937     bool is_init = false;
   3938     if (actual_arg_type.IsUninitializedTypes()) {
   3939       if (res_method) {
   3940         if (!res_method->IsConstructor()) {
   3941           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   3942           return nullptr;
   3943         }
   3944       } else {
   3945         // Check whether the name of the called method is "<init>"
   3946         const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
   3947         if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) {
   3948           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   3949           return nullptr;
   3950         }
   3951       }
   3952       is_init = true;
   3953     }
   3954     const RegType& adjusted_type = is_init
   3955                                        ? GetRegTypeCache()->FromUninitialized(actual_arg_type)
   3956                                        : actual_arg_type;
   3957     if (method_type != METHOD_INTERFACE && !adjusted_type.IsZeroOrNull()) {
   3958       const RegType* res_method_class;
   3959       // Miranda methods have the declaring interface as their declaring class, not the abstract
   3960       // class. It would be wrong to use this for the type check (interface type checks are
   3961       // postponed to runtime).
   3962       if (res_method != nullptr && !res_method->IsMiranda()) {
   3963         mirror::Class* klass = res_method->GetDeclaringClass();
   3964         std::string temp;
   3965         res_method_class = &FromClass(klass->GetDescriptor(&temp), klass,
   3966                                       klass->CannotBeAssignedFromOtherTypes());
   3967       } else {
   3968         const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
   3969         const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
   3970         res_method_class = &reg_types_.FromDescriptor(
   3971             GetClassLoader(),
   3972             dex_file_->StringByTypeIdx(class_idx),
   3973             false);
   3974       }
   3975       if (!res_method_class->IsAssignableFrom(adjusted_type, this)) {
   3976         Fail(adjusted_type.IsUnresolvedTypes()
   3977                  ? VERIFY_ERROR_NO_CLASS
   3978                  : VERIFY_ERROR_BAD_CLASS_SOFT)
   3979             << "'this' argument '" << actual_arg_type << "' not instance of '"
   3980             << *res_method_class << "'";
   3981         // Continue on soft failures. We need to find possible hard failures to avoid problems in
   3982         // the compiler.
   3983         if (have_pending_hard_failure_) {
   3984           return nullptr;
   3985         }
   3986       }
   3987     }
   3988   }
   3989 
   3990   uint32_t arg[5];
   3991   if (!is_range) {
   3992     inst->GetVarArgs(arg);
   3993   }
   3994   uint32_t sig_registers = (method_type == METHOD_STATIC) ? 0 : 1;
   3995   for ( ; it->HasNext(); it->Next()) {
   3996     if (sig_registers >= expected_args) {
   3997       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() <<
   3998           " argument registers, method signature has " << sig_registers + 1 << " or more";
   3999       return nullptr;
   4000     }
   4001 
   4002     const char* param_descriptor = it->GetDescriptor();
   4003 
   4004     if (param_descriptor == nullptr) {
   4005       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation because of missing signature "
   4006           "component";
   4007       return nullptr;
   4008     }
   4009 
   4010     const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), param_descriptor, false);
   4011     uint32_t get_reg = is_range ? inst->VRegC() + static_cast<uint32_t>(sig_registers) :
   4012         arg[sig_registers];
   4013     if (reg_type.IsIntegralTypes()) {
   4014       const RegType& src_type = work_line_->GetRegisterType(this, get_reg);
   4015       if (!src_type.IsIntegralTypes()) {
   4016         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type
   4017             << " but expected " << reg_type;
   4018         return nullptr;
   4019       }
   4020     } else {
   4021       if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) {
   4022         // Continue on soft failures. We need to find possible hard failures to avoid problems in
   4023         // the compiler.
   4024         if (have_pending_hard_failure_) {
   4025           return nullptr;
   4026         }
   4027       } else if (reg_type.IsLongOrDoubleTypes()) {
   4028         // Check that registers are consecutive (for non-range invokes). Invokes are the only
   4029         // instructions not specifying register pairs by the first component, but require them
   4030         // nonetheless. Only check when there's an actual register in the parameters. If there's
   4031         // none, this will fail below.
   4032         if (!is_range && sig_registers + 1 < expected_args) {
   4033           uint32_t second_reg = arg[sig_registers + 1];
   4034           if (second_reg != get_reg + 1) {
   4035             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, long or double parameter "
   4036                 "at index " << sig_registers << " is not a pair: " << get_reg << " + "
   4037                 << second_reg << ".";
   4038             return nullptr;
   4039           }
   4040         }
   4041       }
   4042     }
   4043     sig_registers += reg_type.IsLongOrDoubleTypes() ?  2 : 1;
   4044   }
   4045   if (expected_args != sig_registers) {
   4046     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args <<
   4047         " argument registers, method signature has " << sig_registers;
   4048     return nullptr;
   4049   }
   4050   return res_method;
   4051 }
   4052 
   4053 void MethodVerifier::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst,
   4054                                                           MethodType method_type,
   4055                                                           bool is_range) {
   4056   // As the method may not have been resolved, make this static check against what we expect.
   4057   // The main reason for this code block is to fail hard when we find an illegal use, e.g.,
   4058   // wrong number of arguments or wrong primitive types, even if the method could not be resolved.
   4059   const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
   4060   DexFileParameterIterator it(*dex_file_,
   4061                               dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_));
   4062   VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, nullptr);
   4063 }
   4064 
   4065 bool MethodVerifier::CheckCallSite(uint32_t call_site_idx) {
   4066   if (call_site_idx >= dex_file_->NumCallSiteIds()) {
   4067     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Bad call site id #" << call_site_idx
   4068                                       << " >= " << dex_file_->NumCallSiteIds();
   4069     return false;
   4070   }
   4071 
   4072   CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx));
   4073   // Check essential arguments are provided. The dex file verifier has verified indicies of the
   4074   // main values (method handle, name, method_type).
   4075   if (it.Size() < 3) {
   4076     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4077                                       << " has too few arguments: "
   4078                                       << it.Size() << "< 3";
   4079     return false;
   4080   }
   4081 
   4082   // Get and check the first argument: the method handle (index range
   4083   // checked by the dex file verifier).
   4084   uint32_t method_handle_idx = static_cast<uint32_t>(it.GetJavaValue().i);
   4085   it.Next();
   4086 
   4087   const DexFile::MethodHandleItem& mh = dex_file_->GetMethodHandle(method_handle_idx);
   4088   if (mh.method_handle_type_ != static_cast<uint16_t>(DexFile::MethodHandleType::kInvokeStatic)) {
   4089     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4090                                       << " argument 0 method handle type is not InvokeStatic: "
   4091                                       << mh.method_handle_type_;
   4092     return false;
   4093   }
   4094 
   4095   // Skip the second argument, the name to resolve, as checked by the
   4096   // dex file verifier.
   4097   it.Next();
   4098 
   4099   // Skip the third argument, the method type expected, as checked by
   4100   // the dex file verifier.
   4101   it.Next();
   4102 
   4103   // Check the bootstrap method handle and remaining arguments.
   4104   const DexFile::MethodId& method_id = dex_file_->GetMethodId(mh.field_or_method_idx_);
   4105   uint32_t length;
   4106   const char* shorty = dex_file_->GetMethodShorty(method_id, &length);
   4107 
   4108   if (it.Size() < length - 1) {
   4109     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4110                                       << " too few arguments for bootstrap method: "
   4111                                       << it.Size() << " < " << (length - 1);
   4112     return false;
   4113   }
   4114 
   4115   // Check the return type and first 3 arguments are references
   4116   // (CallSite, Lookup, String, MethodType). If they are not of the
   4117   // expected types (or subtypes), it will trigger a
   4118   // WrongMethodTypeException during execution.
   4119   if (shorty[0] != 'L') {
   4120     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4121                                       << " bootstrap return type is not a reference";
   4122     return false;
   4123   }
   4124 
   4125   for (uint32_t i = 1; i < 4; ++i) {
   4126     if (shorty[i] != 'L') {
   4127       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4128                                         << " bootstrap method argument " << (i - 1)
   4129                                         << " is not a reference";
   4130       return false;
   4131     }
   4132   }
   4133 
   4134   // Check the optional arguments.
   4135   for (uint32_t i = 4; i < length; ++i, it.Next()) {
   4136     bool match = false;
   4137     switch (it.GetValueType()) {
   4138       case EncodedArrayValueIterator::ValueType::kBoolean:
   4139       case EncodedArrayValueIterator::ValueType::kByte:
   4140       case EncodedArrayValueIterator::ValueType::kShort:
   4141       case EncodedArrayValueIterator::ValueType::kChar:
   4142       case EncodedArrayValueIterator::ValueType::kInt:
   4143         // These all fit within one register and encoders do not seem
   4144         // too exacting on the encoding type they use (ie using
   4145         // integer for all of these).
   4146         match = (strchr("ZBCSI", shorty[i]) != nullptr);
   4147         break;
   4148       case EncodedArrayValueIterator::ValueType::kLong:
   4149         match = ('J' == shorty[i]);
   4150         break;
   4151       case EncodedArrayValueIterator::ValueType::kFloat:
   4152         match = ('F' == shorty[i]);
   4153         break;
   4154       case EncodedArrayValueIterator::ValueType::kDouble:
   4155         match = ('D' == shorty[i]);
   4156         break;
   4157       case EncodedArrayValueIterator::ValueType::kMethodType:
   4158       case EncodedArrayValueIterator::ValueType::kMethodHandle:
   4159       case EncodedArrayValueIterator::ValueType::kString:
   4160       case EncodedArrayValueIterator::ValueType::kType:
   4161       case EncodedArrayValueIterator::ValueType::kNull:
   4162         match = ('L' == shorty[i]);
   4163         break;
   4164       case EncodedArrayValueIterator::ValueType::kField:
   4165       case EncodedArrayValueIterator::ValueType::kMethod:
   4166       case EncodedArrayValueIterator::ValueType::kEnum:
   4167       case EncodedArrayValueIterator::ValueType::kArray:
   4168       case EncodedArrayValueIterator::ValueType::kAnnotation:
   4169         // Unreachable based on current EncodedArrayValueIterator::Next().
   4170         UNREACHABLE();
   4171     }
   4172 
   4173     if (!match) {
   4174       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4175                                         << " bootstrap method argument " << (i - 1)
   4176                                         << " expected " << shorty[i]
   4177                                         << " got value type: " << it.GetValueType();
   4178       return false;
   4179     }
   4180   }
   4181   return true;
   4182 }
   4183 
   4184 class MethodParamListDescriptorIterator {
   4185  public:
   4186   explicit MethodParamListDescriptorIterator(ArtMethod* res_method) :
   4187       res_method_(res_method), pos_(0), params_(res_method->GetParameterTypeList()),
   4188       params_size_(params_ == nullptr ? 0 : params_->Size()) {
   4189   }
   4190 
   4191   bool HasNext() {
   4192     return pos_ < params_size_;
   4193   }
   4194 
   4195   void Next() {
   4196     ++pos_;
   4197   }
   4198 
   4199   const char* GetDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
   4200     return res_method_->GetTypeDescriptorFromTypeIdx(params_->GetTypeItem(pos_).type_idx_);
   4201   }
   4202 
   4203  private:
   4204   ArtMethod* res_method_;
   4205   size_t pos_;
   4206   const DexFile::TypeList* params_;
   4207   const size_t params_size_;
   4208 };
   4209 
   4210 ArtMethod* MethodVerifier::VerifyInvocationArgs(
   4211     const Instruction* inst, MethodType method_type, bool is_range) {
   4212   // Resolve the method. This could be an abstract or concrete method depending on what sort of call
   4213   // we're making.
   4214   const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
   4215   ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type);
   4216   if (res_method == nullptr) {  // error or class is unresolved
   4217     // Check what we can statically.
   4218     if (!have_pending_hard_failure_) {
   4219       VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
   4220     }
   4221     return nullptr;
   4222   }
   4223 
   4224   // If we're using invoke-super(method), make sure that the executing method's class' superclass
   4225   // has a vtable entry for the target method. Or the target is on a interface.
   4226   if (method_type == METHOD_SUPER) {
   4227     dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
   4228     const RegType& reference_type = reg_types_.FromDescriptor(
   4229         GetClassLoader(),
   4230         dex_file_->StringByTypeIdx(class_idx),
   4231         false);
   4232     if (reference_type.IsUnresolvedTypes()) {
   4233       Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Unable to find referenced class from invoke-super";
   4234       return nullptr;
   4235     }
   4236     if (reference_type.GetClass()->IsInterface()) {
   4237       // TODO Can we verify anything else.
   4238       if (class_idx == class_def_.class_idx_) {
   4239         Fail(VERIFY_ERROR_CLASS_CHANGE) << "Cannot invoke-super on self as interface";
   4240         return nullptr;
   4241       }
   4242       // TODO Revisit whether we want to allow invoke-super on direct interfaces only like the JLS
   4243       // does.
   4244       if (!GetDeclaringClass().HasClass()) {
   4245         Fail(VERIFY_ERROR_NO_CLASS) << "Unable to resolve the full class of 'this' used in an"
   4246                                     << "interface invoke-super";
   4247         return nullptr;
   4248       } else if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this)) {
   4249         Fail(VERIFY_ERROR_CLASS_CHANGE)
   4250             << "invoke-super in " << mirror::Class::PrettyClass(GetDeclaringClass().GetClass())
   4251             << " in method "
   4252             << dex_file_->PrettyMethod(dex_method_idx_) << " to method "
   4253             << dex_file_->PrettyMethod(method_idx) << " references "
   4254             << "non-super-interface type " << mirror::Class::PrettyClass(reference_type.GetClass());
   4255         return nullptr;
   4256       }
   4257     } else {
   4258       const RegType& super = GetDeclaringClass().GetSuperClass(&reg_types_);
   4259       if (super.IsUnresolvedTypes()) {
   4260         Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from "
   4261                                     << dex_file_->PrettyMethod(dex_method_idx_)
   4262                                     << " to super " << res_method->PrettyMethod();
   4263         return nullptr;
   4264       }
   4265       if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this) ||
   4266           (res_method->GetMethodIndex() >= super.GetClass()->GetVTableLength())) {
   4267         Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
   4268                                     << dex_file_->PrettyMethod(dex_method_idx_)
   4269                                     << " to super " << super
   4270                                     << "." << res_method->GetName()
   4271                                     << res_method->GetSignature();
   4272         return nullptr;
   4273       }
   4274     }
   4275   }
   4276 
   4277   if (UNLIKELY(method_type == METHOD_POLYMORPHIC)) {
   4278     // Process the signature of the calling site that is invoking the method handle.
   4279     DexFileParameterIterator it(*dex_file_, dex_file_->GetProtoId(inst->VRegH()));
   4280     return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method);
   4281   } else {
   4282     // Process the target method's signature.
   4283     MethodParamListDescriptorIterator it(res_method);
   4284     return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method);
   4285   }
   4286 }
   4287 
   4288 bool MethodVerifier::CheckSignaturePolymorphicMethod(ArtMethod* method) {
   4289   mirror::Class* klass = method->GetDeclaringClass();
   4290   const char* method_name = method->GetName();
   4291 
   4292   const char* expected_return_descriptor;
   4293   if (klass == mirror::MethodHandle::StaticClass()) {
   4294     expected_return_descriptor = mirror::MethodHandle::GetReturnTypeDescriptor(method_name);
   4295   } else if (klass == mirror::VarHandle::StaticClass()) {
   4296     expected_return_descriptor = mirror::VarHandle::GetReturnTypeDescriptor(method_name);
   4297     // TODO: add compiler support for VarHandle accessor methods (b/71781600)
   4298     Fail(VERIFY_ERROR_FORCE_INTERPRETER);
   4299   } else {
   4300     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4301         << "Signature polymorphic method in unsuppported class: " << klass->PrettyDescriptor();
   4302     return false;
   4303   }
   4304 
   4305   if (expected_return_descriptor == nullptr) {
   4306     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4307         << "Signature polymorphic method name invalid: " << method_name;
   4308     return false;
   4309   }
   4310 
   4311   const DexFile::TypeList* types = method->GetParameterTypeList();
   4312   if (types->Size() != 1) {
   4313     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4314         << "Signature polymorphic method has too many arguments " << types->Size() << " != 1";
   4315     return false;
   4316   }
   4317 
   4318   const dex::TypeIndex argument_type_index = types->GetTypeItem(0).type_idx_;
   4319   const char* argument_descriptor = method->GetTypeDescriptorFromTypeIdx(argument_type_index);
   4320   if (strcmp(argument_descriptor, "[Ljava/lang/Object;") != 0) {
   4321     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4322         << "Signature polymorphic method has unexpected argument type: " << argument_descriptor;
   4323     return false;
   4324   }
   4325 
   4326   const char* return_descriptor = method->GetReturnTypeDescriptor();
   4327   if (strcmp(return_descriptor, expected_return_descriptor) != 0) {
   4328     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4329         << "Signature polymorphic method has unexpected return type: " << return_descriptor
   4330         << " != " << expected_return_descriptor;
   4331     return false;
   4332   }
   4333 
   4334   return true;
   4335 }
   4336 
   4337 bool MethodVerifier::CheckSignaturePolymorphicReceiver(const Instruction* inst) {
   4338   const RegType& this_type = work_line_->GetInvocationThis(this, inst);
   4339   if (this_type.IsZeroOrNull()) {
   4340     /* null pointer always passes (and always fails at run time) */
   4341     return true;
   4342   } else if (!this_type.IsNonZeroReferenceTypes()) {
   4343     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4344         << "invoke-polymorphic receiver is not a reference: "
   4345         << this_type;
   4346     return false;
   4347   } else if (this_type.IsUninitializedReference()) {
   4348     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4349         << "invoke-polymorphic receiver is uninitialized: "
   4350         << this_type;
   4351     return false;
   4352   } else if (!this_type.HasClass()) {
   4353     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4354         << "invoke-polymorphic receiver has no class: "
   4355         << this_type;
   4356     return false;
   4357   } else if (!this_type.GetClass()->IsSubClass(mirror::MethodHandle::StaticClass()) &&
   4358              !this_type.GetClass()->IsSubClass(mirror::VarHandle::StaticClass())) {
   4359     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4360         << "invoke-polymorphic receiver is not a subclass of MethodHandle or VarHandle: "
   4361         << this_type;
   4362     return false;
   4363   }
   4364   return true;
   4365 }
   4366 
   4367 uint16_t MethodVerifier::GetMethodIdxOfInvoke(const Instruction* inst) {
   4368   switch (inst->Opcode()) {
   4369     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK:
   4370     case Instruction::INVOKE_VIRTUAL_QUICK: {
   4371       DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_)
   4372           << dex_file_->PrettyMethod(dex_method_idx_, true) << "@" << work_insn_idx_;
   4373       DCHECK(method_being_verified_ != nullptr);
   4374       uint16_t method_idx = method_being_verified_->GetIndexFromQuickening(work_insn_idx_);
   4375       CHECK_NE(method_idx, DexFile::kDexNoIndex16);
   4376       return method_idx;
   4377     }
   4378     default: {
   4379       return inst->VRegB();
   4380     }
   4381   }
   4382 }
   4383 
   4384 uint16_t MethodVerifier::GetFieldIdxOfFieldAccess(const Instruction* inst, bool is_static) {
   4385   if (is_static) {
   4386     return inst->VRegB_21c();
   4387   } else if (inst->IsQuickened()) {
   4388     DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
   4389     DCHECK(method_being_verified_ != nullptr);
   4390     uint16_t field_idx = method_being_verified_->GetIndexFromQuickening(work_insn_idx_);
   4391     CHECK_NE(field_idx, DexFile::kDexNoIndex16);
   4392     return field_idx;
   4393   } else {
   4394     return inst->VRegC_22c();
   4395   }
   4396 }
   4397 
   4398 void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) {
   4399   dex::TypeIndex type_idx;
   4400   if (!is_filled) {
   4401     DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY);
   4402     type_idx = dex::TypeIndex(inst->VRegC_22c());
   4403   } else if (!is_range) {
   4404     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY);
   4405     type_idx = dex::TypeIndex(inst->VRegB_35c());
   4406   } else {
   4407     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE);
   4408     type_idx = dex::TypeIndex(inst->VRegB_3rc());
   4409   }
   4410   const RegType& res_type = ResolveClass<CheckAccess::kYes>(type_idx);
   4411   if (res_type.IsConflict()) {  // bad class
   4412     DCHECK_NE(failures_.size(), 0U);
   4413   } else {
   4414     // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   4415     if (!res_type.IsArrayTypes()) {
   4416       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type;
   4417     } else if (!is_filled) {
   4418       /* make sure "size" register is valid type */
   4419       work_line_->VerifyRegisterType(this, inst->VRegB_22c(), reg_types_.Integer());
   4420       /* set register type to array class */
   4421       const RegType& precise_type = reg_types_.FromUninitialized(res_type);
   4422       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_22c(), precise_type);
   4423     } else {
   4424       DCHECK(!res_type.IsUnresolvedMergedReference());
   4425       // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
   4426       // the list and fail. It's legal, if silly, for arg_count to be zero.
   4427       const RegType& expected_type = reg_types_.GetComponentType(res_type, GetClassLoader());
   4428       uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
   4429       uint32_t arg[5];
   4430       if (!is_range) {
   4431         inst->GetVarArgs(arg);
   4432       }
   4433       for (size_t ui = 0; ui < arg_count; ui++) {
   4434         uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui];
   4435         if (!work_line_->VerifyRegisterType(this, get_reg, expected_type)) {
   4436           work_line_->SetResultRegisterType(this, reg_types_.Conflict());
   4437           return;
   4438         }
   4439       }
   4440       // filled-array result goes into "result" register
   4441       const RegType& precise_type = reg_types_.FromUninitialized(res_type);
   4442       work_line_->SetResultRegisterType(this, precise_type);
   4443     }
   4444   }
   4445 }
   4446 
   4447 void MethodVerifier::VerifyAGet(const Instruction* inst,
   4448                                 const RegType& insn_type, bool is_primitive) {
   4449   const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
   4450   if (!index_type.IsArrayIndexTypes()) {
   4451     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
   4452   } else {
   4453     const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
   4454     if (array_type.IsZeroOrNull()) {
   4455       // Null array class; this code path will fail at runtime. Infer a merge-able type from the
   4456       // instruction type.
   4457       if (!is_primitive) {
   4458         work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Null());
   4459       } else if (insn_type.IsInteger()) {
   4460         // Pick a non-zero constant (to distinguish with null) that can fit in any primitive.
   4461         // We cannot use 'insn_type' as it could be a float array or an int array.
   4462         work_line_->SetRegisterType<LockOp::kClear>(
   4463             this, inst->VRegA_23x(), DetermineCat1Constant(1, need_precise_constants_));
   4464       } else if (insn_type.IsCategory1Types()) {
   4465         // Category 1
   4466         // The 'insn_type' is exactly the type we need.
   4467         work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), insn_type);
   4468       } else {
   4469         // Category 2
   4470         work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(),
   4471                                         reg_types_.FromCat2ConstLo(0, false),
   4472                                         reg_types_.FromCat2ConstHi(0, false));
   4473       }
   4474     } else if (!array_type.IsArrayTypes()) {
   4475       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget";
   4476     } else if (array_type.IsUnresolvedMergedReference()) {
   4477       // Unresolved array types must be reference array types.
   4478       if (is_primitive) {
   4479         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
   4480                     << " source for category 1 aget";
   4481       } else {
   4482         Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aget for " << array_type
   4483             << " because of missing class";
   4484         // Approximate with java.lang.Object[].
   4485         work_line_->SetRegisterType<LockOp::kClear>(this,
   4486                                                     inst->VRegA_23x(),
   4487                                                     reg_types_.JavaLangObject(false));
   4488       }
   4489     } else {
   4490       /* verify the class */
   4491       const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
   4492       if (!component_type.IsReferenceTypes() && !is_primitive) {
   4493         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
   4494             << " source for aget-object";
   4495       } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) {
   4496         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
   4497             << " source for category 1 aget";
   4498       } else if (is_primitive && !insn_type.Equals(component_type) &&
   4499                  !((insn_type.IsInteger() && component_type.IsFloat()) ||
   4500                  (insn_type.IsLong() && component_type.IsDouble()))) {
   4501         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type
   4502             << " incompatible with aget of type " << insn_type;
   4503       } else {
   4504         // Use knowledge of the field type which is stronger than the type inferred from the
   4505         // instruction, which can't differentiate object types and ints from floats, longs from
   4506         // doubles.
   4507         if (!component_type.IsLowHalf()) {
   4508           work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), component_type);
   4509         } else {
   4510           work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), component_type,
   4511                                           component_type.HighHalf(&reg_types_));
   4512         }
   4513       }
   4514     }
   4515   }
   4516 }
   4517 
   4518 void MethodVerifier::VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type,
   4519                                         const uint32_t vregA) {
   4520   // Primitive assignability rules are weaker than regular assignability rules.
   4521   bool instruction_compatible;
   4522   bool value_compatible;
   4523   const RegType& value_type = work_line_->GetRegisterType(this, vregA);
   4524   if (target_type.IsIntegralTypes()) {
   4525     instruction_compatible = target_type.Equals(insn_type);
   4526     value_compatible = value_type.IsIntegralTypes();
   4527   } else if (target_type.IsFloat()) {
   4528     instruction_compatible = insn_type.IsInteger();  // no put-float, so expect put-int
   4529     value_compatible = value_type.IsFloatTypes();
   4530   } else if (target_type.IsLong()) {
   4531     instruction_compatible = insn_type.IsLong();
   4532     // Additional register check: this is not checked statically (as part of VerifyInstructions),
   4533     // as target_type depends on the resolved type of the field.
   4534     if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
   4535       const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
   4536       value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
   4537     } else {
   4538       value_compatible = false;
   4539     }
   4540   } else if (target_type.IsDouble()) {
   4541     instruction_compatible = insn_type.IsLong();  // no put-double, so expect put-long
   4542     // Additional register check: this is not checked statically (as part of VerifyInstructions),
   4543     // as target_type depends on the resolved type of the field.
   4544     if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
   4545       const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
   4546       value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
   4547     } else {
   4548       value_compatible = false;
   4549     }
   4550   } else {
   4551     instruction_compatible = false;  // reference with primitive store
   4552     value_compatible = false;  // unused
   4553   }
   4554   if (!instruction_compatible) {
   4555     // This is a global failure rather than a class change failure as the instructions and
   4556     // the descriptors for the type should have been consistent within the same file at
   4557     // compile time.
   4558     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
   4559         << "' but expected type '" << target_type << "'";
   4560     return;
   4561   }
   4562   if (!value_compatible) {
   4563     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
   4564         << " of type " << value_type << " but expected " << target_type << " for put";
   4565     return;
   4566   }
   4567 }
   4568 
   4569 void MethodVerifier::VerifyAPut(const Instruction* inst,
   4570                                 const RegType& insn_type, bool is_primitive) {
   4571   const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
   4572   if (!index_type.IsArrayIndexTypes()) {
   4573     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
   4574   } else {
   4575     const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
   4576     if (array_type.IsZeroOrNull()) {
   4577       // Null array type; this code path will fail at runtime.
   4578       // Still check that the given value matches the instruction's type.
   4579       // Note: this is, as usual, complicated by the fact the the instruction isn't fully typed
   4580       //       and fits multiple register types.
   4581       const RegType* modified_reg_type = &insn_type;
   4582       if ((modified_reg_type == &reg_types_.Integer()) ||
   4583           (modified_reg_type == &reg_types_.LongLo())) {
   4584         // May be integer or float | long or double. Overwrite insn_type accordingly.
   4585         const RegType& value_type = work_line_->GetRegisterType(this, inst->VRegA_23x());
   4586         if (modified_reg_type == &reg_types_.Integer()) {
   4587           if (&value_type == &reg_types_.Float()) {
   4588             modified_reg_type = &value_type;
   4589           }
   4590         } else {
   4591           if (&value_type == &reg_types_.DoubleLo()) {
   4592             modified_reg_type = &value_type;
   4593           }
   4594         }
   4595       }
   4596       work_line_->VerifyRegisterType(this, inst->VRegA_23x(), *modified_reg_type);
   4597     } else if (!array_type.IsArrayTypes()) {
   4598       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
   4599     } else if (array_type.IsUnresolvedMergedReference()) {
   4600       // Unresolved array types must be reference array types.
   4601       if (is_primitive) {
   4602         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
   4603                                           << "' but unresolved type '" << array_type << "'";
   4604       } else {
   4605         Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aput for " << array_type
   4606                                     << " because of missing class";
   4607       }
   4608     } else {
   4609       const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
   4610       const uint32_t vregA = inst->VRegA_23x();
   4611       if (is_primitive) {
   4612         VerifyPrimitivePut(component_type, insn_type, vregA);
   4613       } else {
   4614         if (!component_type.IsReferenceTypes()) {
   4615           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
   4616               << " source for aput-object";
   4617         } else {
   4618           // The instruction agrees with the type of array, confirm the value to be stored does too
   4619           // Note: we use the instruction type (rather than the component type) for aput-object as
   4620           // incompatible classes will be caught at runtime as an array store exception
   4621           work_line_->VerifyRegisterType(this, vregA, insn_type);
   4622         }
   4623       }
   4624     }
   4625   }
   4626 }
   4627 
   4628 ArtField* MethodVerifier::GetStaticField(int field_idx) {
   4629   const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4630   // Check access to class
   4631   const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_);
   4632   if (klass_type.IsConflict()) {  // bad class
   4633     AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s",
   4634                                          field_idx, dex_file_->GetFieldName(field_id),
   4635                                          dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
   4636     return nullptr;
   4637   }
   4638   if (klass_type.IsUnresolvedTypes()) {
   4639     // Accessibility checks depend on resolved fields.
   4640     DCHECK(klass_type.Equals(GetDeclaringClass()) || !failures_.empty());
   4641 
   4642     return nullptr;  // Can't resolve Class so no more to do here, will do checking at runtime.
   4643   }
   4644   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   4645   ArtField* field = class_linker->ResolveFieldJLS(field_idx, dex_cache_, class_loader_);
   4646 
   4647   // Record result of the field resolution attempt.
   4648   VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field);
   4649 
   4650   if (field == nullptr) {
   4651     VLOG(verifier) << "Unable to resolve static field " << field_idx << " ("
   4652               << dex_file_->GetFieldName(field_id) << ") in "
   4653               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   4654     DCHECK(self_->IsExceptionPending());
   4655     self_->ClearException();
   4656     return nullptr;
   4657   } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
   4658                                                   field->GetAccessFlags())) {
   4659     Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access static field " << field->PrettyField()
   4660                                     << " from " << GetDeclaringClass();
   4661     return nullptr;
   4662   } else if (!field->IsStatic()) {
   4663     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() << " to be static";
   4664     return nullptr;
   4665   }
   4666   return field;
   4667 }
   4668 
   4669 ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
   4670   const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4671   // Check access to class.
   4672   const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_);
   4673   if (klass_type.IsConflict()) {
   4674     AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s",
   4675                                          field_idx, dex_file_->GetFieldName(field_id),
   4676                                          dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
   4677     return nullptr;
   4678   }
   4679   if (klass_type.IsUnresolvedTypes()) {
   4680     // Accessibility checks depend on resolved fields.
   4681     DCHECK(klass_type.Equals(GetDeclaringClass()) || !failures_.empty());
   4682 
   4683     return nullptr;  // Can't resolve Class so no more to do here
   4684   }
   4685   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   4686   ArtField* field = class_linker->ResolveFieldJLS(field_idx, dex_cache_, class_loader_);
   4687 
   4688   // Record result of the field resolution attempt.
   4689   VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field);
   4690 
   4691   if (field == nullptr) {
   4692     VLOG(verifier) << "Unable to resolve instance field " << field_idx << " ("
   4693               << dex_file_->GetFieldName(field_id) << ") in "
   4694               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   4695     DCHECK(self_->IsExceptionPending());
   4696     self_->ClearException();
   4697     return nullptr;
   4698   } else if (obj_type.IsZeroOrNull()) {
   4699     // Cannot infer and check type, however, access will cause null pointer exception.
   4700     // Fall through into a few last soft failure checks below.
   4701   } else if (!obj_type.IsReferenceTypes()) {
   4702     // Trying to read a field from something that isn't a reference.
   4703     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
   4704                                       << "non-reference type " << obj_type;
   4705     return nullptr;
   4706   } else {
   4707     std::string temp;
   4708     ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
   4709     const RegType& field_klass =
   4710         FromClass(klass->GetDescriptor(&temp),
   4711                   klass.Ptr(),
   4712                   klass->CannotBeAssignedFromOtherTypes());
   4713     if (obj_type.IsUninitializedTypes()) {
   4714       // Field accesses through uninitialized references are only allowable for constructors where
   4715       // the field is declared in this class.
   4716       // Note: this IsConstructor check is technically redundant, as UninitializedThis should only
   4717       //       appear in constructors.
   4718       if (!obj_type.IsUninitializedThisReference() ||
   4719           !IsConstructor() ||
   4720           !field_klass.Equals(GetDeclaringClass())) {
   4721         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access instance field " << field->PrettyField()
   4722                                           << " of a not fully initialized object within the context"
   4723                                           << " of " << dex_file_->PrettyMethod(dex_method_idx_);
   4724         return nullptr;
   4725       }
   4726     } else if (!field_klass.IsAssignableFrom(obj_type, this)) {
   4727       // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class
   4728       // of C1. For resolution to occur the declared class of the field must be compatible with
   4729       // obj_type, we've discovered this wasn't so, so report the field didn't exist.
   4730       VerifyError type;
   4731       bool is_aot = Runtime::Current()->IsAotCompiler();
   4732       if (is_aot && (field_klass.IsUnresolvedTypes() || obj_type.IsUnresolvedTypes())) {
   4733         // Compiler & unresolved types involved, retry at runtime.
   4734         type = VerifyError::VERIFY_ERROR_NO_CLASS;
   4735       } else {
   4736         // Classes known (resolved; and thus assignability check is precise), or we are at runtime
   4737         // and still missing classes. This is a hard failure.
   4738         type = VerifyError::VERIFY_ERROR_BAD_CLASS_HARD;
   4739       }
   4740       Fail(type) << "cannot access instance field " << field->PrettyField()
   4741                  << " from object of type " << obj_type;
   4742       return nullptr;
   4743     }
   4744   }
   4745 
   4746   // Few last soft failure checks.
   4747   if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
   4748                                            field->GetAccessFlags())) {
   4749     Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access instance field " << field->PrettyField()
   4750                                     << " from " << GetDeclaringClass();
   4751     return nullptr;
   4752   } else if (field->IsStatic()) {
   4753     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField()
   4754                                     << " to not be static";
   4755     return nullptr;
   4756   }
   4757 
   4758   return field;
   4759 }
   4760 
   4761 template <MethodVerifier::FieldAccessType kAccType>
   4762 void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType& insn_type,
   4763                                          bool is_primitive, bool is_static) {
   4764   uint32_t field_idx = GetFieldIdxOfFieldAccess(inst, is_static);
   4765   ArtField* field;
   4766   if (is_static) {
   4767     field = GetStaticField(field_idx);
   4768   } else {
   4769     const RegType& object_type = work_line_->GetRegisterType(this, inst->VRegB_22c());
   4770 
   4771     // One is not allowed to access fields on uninitialized references, except to write to
   4772     // fields in the constructor (before calling another constructor).
   4773     // GetInstanceField does an assignability check which will fail for uninitialized types.
   4774     // We thus modify the type if the uninitialized reference is a "this" reference (this also
   4775     // checks at the same time that we're verifying a constructor).
   4776     bool should_adjust = (kAccType == FieldAccessType::kAccPut) &&
   4777                          object_type.IsUninitializedThisReference();
   4778     const RegType& adjusted_type = should_adjust
   4779                                        ? GetRegTypeCache()->FromUninitialized(object_type)
   4780                                        : object_type;
   4781     field = GetInstanceField(adjusted_type, field_idx);
   4782     if (UNLIKELY(have_pending_hard_failure_)) {
   4783       return;
   4784     }
   4785     if (should_adjust) {
   4786       if (field == nullptr) {
   4787         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Might be accessing a superclass instance field prior "
   4788                                           << "to the superclass being initialized in "
   4789                                           << dex_file_->PrettyMethod(dex_method_idx_);
   4790       } else if (field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   4791         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access superclass instance field "
   4792                                           << field->PrettyField() << " of a not fully initialized "
   4793                                           << "object within the context of "
   4794                                           << dex_file_->PrettyMethod(dex_method_idx_);
   4795         return;
   4796       }
   4797     }
   4798   }
   4799   const RegType* field_type = nullptr;
   4800   if (field != nullptr) {
   4801     if (kAccType == FieldAccessType::kAccPut) {
   4802       if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   4803         Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << field->PrettyField()
   4804                                         << " from other class " << GetDeclaringClass();
   4805         // Keep hunting for possible hard fails.
   4806       }
   4807     }
   4808 
   4809     ObjPtr<mirror::Class> field_type_class =
   4810         can_load_classes_ ? field->ResolveType() : field->LookupResolvedType();
   4811     if (field_type_class != nullptr) {
   4812       field_type = &FromClass(field->GetTypeDescriptor(),
   4813                               field_type_class.Ptr(),
   4814                               field_type_class->CannotBeAssignedFromOtherTypes());
   4815     } else {
   4816       DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   4817       self_->ClearException();
   4818     }
   4819   } else {
   4820     // If we don't have the field (it seems we failed resolution) and this is a PUT, we need to
   4821     // redo verification at runtime as the field may be final, unless the field id shows it's in
   4822     // the same class.
   4823     //
   4824     // For simplicity, it is OK to not distinguish compile-time vs runtime, and post this an
   4825     // ACCESS_FIELD failure at runtime. This has the same effect as NO_FIELD - punting the class
   4826     // to the access-checks interpreter.
   4827     //
   4828     // Note: see b/34966607. This and above may be changed in the future.
   4829     if (kAccType == FieldAccessType::kAccPut) {
   4830       const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4831       const char* field_class_descriptor = dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   4832       const RegType* field_class_type = &reg_types_.FromDescriptor(GetClassLoader(),
   4833                                                                    field_class_descriptor,
   4834                                                                    false);
   4835       if (!field_class_type->Equals(GetDeclaringClass())) {
   4836         Fail(VERIFY_ERROR_ACCESS_FIELD) << "could not check field put for final field modify of "
   4837                                         << field_class_descriptor
   4838                                         << "."
   4839                                         << dex_file_->GetFieldName(field_id)
   4840                                         << " from other class "
   4841                                         << GetDeclaringClass();
   4842       }
   4843     }
   4844   }
   4845   if (field_type == nullptr) {
   4846     const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4847     const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
   4848     field_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   4849   }
   4850   DCHECK(field_type != nullptr);
   4851   const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
   4852   static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet,
   4853                 "Unexpected third access type");
   4854   if (kAccType == FieldAccessType::kAccPut) {
   4855     // sput or iput.
   4856     if (is_primitive) {
   4857       VerifyPrimitivePut(*field_type, insn_type, vregA);
   4858     } else {
   4859       if (!insn_type.IsAssignableFrom(*field_type, this)) {
   4860         // If the field type is not a reference, this is a global failure rather than
   4861         // a class change failure as the instructions and the descriptors for the type
   4862         // should have been consistent within the same file at compile time.
   4863         VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT
   4864                                                            : VERIFY_ERROR_BAD_CLASS_HARD;
   4865         Fail(error) << "expected field " << ArtField::PrettyField(field)
   4866                     << " to be compatible with type '" << insn_type
   4867                     << "' but found type '" << *field_type
   4868                     << "' in put-object";
   4869         return;
   4870       }
   4871       work_line_->VerifyRegisterType(this, vregA, *field_type);
   4872     }
   4873   } else if (kAccType == FieldAccessType::kAccGet) {
   4874     // sget or iget.
   4875     if (is_primitive) {
   4876       if (field_type->Equals(insn_type) ||
   4877           (field_type->IsFloat() && insn_type.IsInteger()) ||
   4878           (field_type->IsDouble() && insn_type.IsLong())) {
   4879         // expected that read is of the correct primitive type or that int reads are reading
   4880         // floats or long reads are reading doubles
   4881       } else {
   4882         // This is a global failure rather than a class change failure as the instructions and
   4883         // the descriptors for the type should have been consistent within the same file at
   4884         // compile time
   4885         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field)
   4886                                           << " to be of type '" << insn_type
   4887                                           << "' but found type '" << *field_type << "' in get";
   4888         return;
   4889       }
   4890     } else {
   4891       if (!insn_type.IsAssignableFrom(*field_type, this)) {
   4892         // If the field type is not a reference, this is a global failure rather than
   4893         // a class change failure as the instructions and the descriptors for the type
   4894         // should have been consistent within the same file at compile time.
   4895         VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT
   4896                                                            : VERIFY_ERROR_BAD_CLASS_HARD;
   4897         Fail(error) << "expected field " << ArtField::PrettyField(field)
   4898                     << " to be compatible with type '" << insn_type
   4899                     << "' but found type '" << *field_type
   4900                     << "' in get-object";
   4901         if (error != VERIFY_ERROR_BAD_CLASS_HARD) {
   4902           work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict());
   4903         }
   4904         return;
   4905       }
   4906     }
   4907     if (!field_type->IsLowHalf()) {
   4908       work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type);
   4909     } else {
   4910       work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(&reg_types_));
   4911     }
   4912   } else {
   4913     LOG(FATAL) << "Unexpected case.";
   4914   }
   4915 }
   4916 
   4917 bool MethodVerifier::CheckNotMoveException(const uint16_t* insns, int insn_idx) {
   4918   if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) {
   4919     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception";
   4920     return false;
   4921   }
   4922   return true;
   4923 }
   4924 
   4925 bool MethodVerifier::CheckNotMoveResult(const uint16_t* insns, int insn_idx) {
   4926   if (((insns[insn_idx] & 0xff) >= Instruction::MOVE_RESULT) &&
   4927       ((insns[insn_idx] & 0xff) <= Instruction::MOVE_RESULT_OBJECT)) {
   4928     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-result*";
   4929     return false;
   4930   }
   4931   return true;
   4932 }
   4933 
   4934 bool MethodVerifier::CheckNotMoveExceptionOrMoveResult(const uint16_t* insns, int insn_idx) {
   4935   return (CheckNotMoveException(insns, insn_idx) && CheckNotMoveResult(insns, insn_idx));
   4936 }
   4937 
   4938 bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line,
   4939                                      bool update_merge_line) {
   4940   bool changed = true;
   4941   RegisterLine* target_line = reg_table_.GetLine(next_insn);
   4942   if (!GetInstructionFlags(next_insn).IsVisitedOrChanged()) {
   4943     /*
   4944      * We haven't processed this instruction before, and we haven't touched the registers here, so
   4945      * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the
   4946      * only way a register can transition out of "unknown", so this is not just an optimization.)
   4947      */
   4948     target_line->CopyFromLine(merge_line);
   4949     if (GetInstructionFlags(next_insn).IsReturn()) {
   4950       // Verify that the monitor stack is empty on return.
   4951       merge_line->VerifyMonitorStackEmpty(this);
   4952 
   4953       // For returns we only care about the operand to the return, all other registers are dead.
   4954       // Initialize them as conflicts so they don't add to GC and deoptimization information.
   4955       const Instruction* ret_inst = &code_item_accessor_.InstructionAt(next_insn);
   4956       AdjustReturnLine(this, ret_inst, target_line);
   4957       // Directly bail if a hard failure was found.
   4958       if (have_pending_hard_failure_) {
   4959         return false;
   4960       }
   4961     }
   4962   } else {
   4963     RegisterLineArenaUniquePtr copy;
   4964     if (UNLIKELY(VLOG_IS_ON(verifier_debug))) {
   4965       copy.reset(RegisterLine::Create(target_line->NumRegs(), this));
   4966       copy->CopyFromLine(target_line);
   4967     }
   4968     changed = target_line->MergeRegisters(this, merge_line);
   4969     if (have_pending_hard_failure_) {
   4970       return false;
   4971     }
   4972     if (UNLIKELY(VLOG_IS_ON(verifier_debug)) && changed) {
   4973       LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]"
   4974                       << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n"
   4975                       << copy->Dump(this) << "  MERGE\n"
   4976                       << merge_line->Dump(this) << "  ==\n"
   4977                       << target_line->Dump(this) << "\n";
   4978     }
   4979     if (update_merge_line && changed) {
   4980       merge_line->CopyFromLine(target_line);
   4981     }
   4982   }
   4983   if (changed) {
   4984     GetInstructionFlags(next_insn).SetChanged();
   4985   }
   4986   return true;
   4987 }
   4988 
   4989 InstructionFlags* MethodVerifier::CurrentInsnFlags() {
   4990   return &GetInstructionFlags(work_insn_idx_);
   4991 }
   4992 
   4993 const RegType& MethodVerifier::GetMethodReturnType() {
   4994   if (return_type_ == nullptr) {
   4995     if (method_being_verified_ != nullptr) {
   4996       ObjPtr<mirror::Class> return_type_class = can_load_classes_
   4997           ? method_being_verified_->ResolveReturnType()
   4998           : method_being_verified_->LookupResolvedReturnType();
   4999       if (return_type_class != nullptr) {
   5000         return_type_ = &FromClass(method_being_verified_->GetReturnTypeDescriptor(),
   5001                                   return_type_class.Ptr(),
   5002                                   return_type_class->CannotBeAssignedFromOtherTypes());
   5003       } else {
   5004         DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   5005         self_->ClearException();
   5006       }
   5007     }
   5008     if (return_type_ == nullptr) {
   5009       const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
   5010       const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id);
   5011       dex::TypeIndex return_type_idx = proto_id.return_type_idx_;
   5012       const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx));
   5013       return_type_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   5014     }
   5015   }
   5016   return *return_type_;
   5017 }
   5018 
   5019 const RegType& MethodVerifier::GetDeclaringClass() {
   5020   if (declaring_class_ == nullptr) {
   5021     const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
   5022     const char* descriptor
   5023         = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
   5024     if (method_being_verified_ != nullptr) {
   5025       mirror::Class* klass = method_being_verified_->GetDeclaringClass();
   5026       declaring_class_ = &FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes());
   5027     } else {
   5028       declaring_class_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   5029     }
   5030   }
   5031   return *declaring_class_;
   5032 }
   5033 
   5034 std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) {
   5035   RegisterLine* line = reg_table_.GetLine(dex_pc);
   5036   DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc);
   5037   std::vector<int32_t> result;
   5038   for (size_t i = 0; i < line->NumRegs(); ++i) {
   5039     const RegType& type = line->GetRegisterType(this, i);
   5040     if (type.IsConstant()) {
   5041       result.push_back(type.IsPreciseConstant() ? kConstant : kImpreciseConstant);
   5042       const ConstantType* const_val = down_cast<const ConstantType*>(&type);
   5043       result.push_back(const_val->ConstantValue());
   5044     } else if (type.IsConstantLo()) {
   5045       result.push_back(type.IsPreciseConstantLo() ? kConstant : kImpreciseConstant);
   5046       const ConstantType* const_val = down_cast<const ConstantType*>(&type);
   5047       result.push_back(const_val->ConstantValueLo());
   5048     } else if (type.IsConstantHi()) {
   5049       result.push_back(type.IsPreciseConstantHi() ? kConstant : kImpreciseConstant);
   5050       const ConstantType* const_val = down_cast<const ConstantType*>(&type);
   5051       result.push_back(const_val->ConstantValueHi());
   5052     } else if (type.IsIntegralTypes()) {
   5053       result.push_back(kIntVReg);
   5054       result.push_back(0);
   5055     } else if (type.IsFloat()) {
   5056       result.push_back(kFloatVReg);
   5057       result.push_back(0);
   5058     } else if (type.IsLong()) {
   5059       result.push_back(kLongLoVReg);
   5060       result.push_back(0);
   5061       result.push_back(kLongHiVReg);
   5062       result.push_back(0);
   5063       ++i;
   5064     } else if (type.IsDouble()) {
   5065       result.push_back(kDoubleLoVReg);
   5066       result.push_back(0);
   5067       result.push_back(kDoubleHiVReg);
   5068       result.push_back(0);
   5069       ++i;
   5070     } else if (type.IsUndefined() || type.IsConflict() || type.IsHighHalf()) {
   5071       result.push_back(kUndefined);
   5072       result.push_back(0);
   5073     } else {
   5074       CHECK(type.IsNonZeroReferenceTypes());
   5075       result.push_back(kReferenceVReg);
   5076       result.push_back(0);
   5077     }
   5078   }
   5079   return result;
   5080 }
   5081 
   5082 const RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) {
   5083   if (precise) {
   5084     // Precise constant type.
   5085     return reg_types_.FromCat1Const(value, true);
   5086   } else {
   5087     // Imprecise constant type.
   5088     if (value < -32768) {
   5089       return reg_types_.IntConstant();
   5090     } else if (value < -128) {
   5091       return reg_types_.ShortConstant();
   5092     } else if (value < 0) {
   5093       return reg_types_.ByteConstant();
   5094     } else if (value == 0) {
   5095       return reg_types_.Zero();
   5096     } else if (value == 1) {
   5097       return reg_types_.One();
   5098     } else if (value < 128) {
   5099       return reg_types_.PosByteConstant();
   5100     } else if (value < 32768) {
   5101       return reg_types_.PosShortConstant();
   5102     } else if (value < 65536) {
   5103       return reg_types_.CharConstant();
   5104     } else {
   5105       return reg_types_.IntConstant();
   5106     }
   5107   }
   5108 }
   5109 
   5110 void MethodVerifier::Init() {
   5111   art::verifier::RegTypeCache::Init();
   5112 }
   5113 
   5114 void MethodVerifier::Shutdown() {
   5115   verifier::RegTypeCache::ShutDown();
   5116 }
   5117 
   5118 void MethodVerifier::VisitStaticRoots(RootVisitor* visitor) {
   5119   RegTypeCache::VisitStaticRoots(visitor);
   5120 }
   5121 
   5122 void MethodVerifier::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) {
   5123   reg_types_.VisitRoots(visitor, root_info);
   5124 }
   5125 
   5126 const RegType& MethodVerifier::FromClass(const char* descriptor,
   5127                                          mirror::Class* klass,
   5128                                          bool precise) {
   5129   DCHECK(klass != nullptr);
   5130   if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) {
   5131     Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for "
   5132         << "non-instantiable klass " << descriptor;
   5133     precise = false;
   5134   }
   5135   return reg_types_.FromClass(descriptor, klass, precise);
   5136 }
   5137 
   5138 }  // namespace verifier
   5139 }  // namespace art
   5140