method_verifier.cc revision 5cbcde2983d7cb95deb38d39784f03a7192b0061
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 "base/logging.h"
22#include "base/mutex-inl.h"
23#include "class_linker.h"
24#include "compiler_callbacks.h"
25#include "dex_file-inl.h"
26#include "dex_instruction-inl.h"
27#include "dex_instruction_visitor.h"
28#include "field_helper.h"
29#include "gc/accounting/card_table-inl.h"
30#include "indenter.h"
31#include "intern_table.h"
32#include "leb128.h"
33#include "method_helper-inl.h"
34#include "mirror/art_field-inl.h"
35#include "mirror/art_method-inl.h"
36#include "mirror/class.h"
37#include "mirror/class-inl.h"
38#include "mirror/dex_cache-inl.h"
39#include "mirror/object-inl.h"
40#include "mirror/object_array-inl.h"
41#include "reg_type-inl.h"
42#include "register_line-inl.h"
43#include "runtime.h"
44#include "scoped_thread_state_change.h"
45#include "handle_scope-inl.h"
46#include "verifier/dex_gc_map.h"
47
48namespace art {
49namespace verifier {
50
51static constexpr bool kTimeVerifyMethod = !kIsDebugBuild;
52static constexpr bool gDebugVerify = false;
53// TODO: Add a constant to method_verifier to turn on verbose logging?
54
55void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* flags,
56                                 uint32_t insns_size, uint16_t registers_size,
57                                 MethodVerifier* verifier) {
58  DCHECK_GT(insns_size, 0U);
59  register_lines_.reset(new RegisterLine*[insns_size]());
60  size_ = insns_size;
61  for (uint32_t i = 0; i < insns_size; i++) {
62    bool interesting = false;
63    switch (mode) {
64      case kTrackRegsAll:
65        interesting = flags[i].IsOpcode();
66        break;
67      case kTrackCompilerInterestPoints:
68        interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget();
69        break;
70      case kTrackRegsBranches:
71        interesting = flags[i].IsBranchTarget();
72        break;
73      default:
74        break;
75    }
76    if (interesting) {
77      register_lines_[i] = RegisterLine::Create(registers_size, verifier);
78    }
79  }
80}
81
82PcToRegisterLineTable::~PcToRegisterLineTable() {
83  for (size_t i = 0; i < size_; i++) {
84    delete register_lines_[i];
85    if (kIsDebugBuild) {
86      register_lines_[i] = nullptr;
87    }
88  }
89}
90
91MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self,
92                                                        mirror::Class* klass,
93                                                        bool allow_soft_failures,
94                                                        std::string* error) {
95  if (klass->IsVerified()) {
96    return kNoFailure;
97  }
98  bool early_failure = false;
99  std::string failure_message;
100  const DexFile& dex_file = klass->GetDexFile();
101  const DexFile::ClassDef* class_def = klass->GetClassDef();
102  mirror::Class* super = klass->GetSuperClass();
103  std::string temp;
104  if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) {
105    early_failure = true;
106    failure_message = " that has no super class";
107  } else if (super != nullptr && super->IsFinal()) {
108    early_failure = true;
109    failure_message = " that attempts to sub-class final class " + PrettyDescriptor(super);
110  } else if (class_def == nullptr) {
111    early_failure = true;
112    failure_message = " that isn't present in dex file " + dex_file.GetLocation();
113  }
114  if (early_failure) {
115    *error = "Verifier rejected class " + PrettyDescriptor(klass) + failure_message;
116    if (Runtime::Current()->IsCompiler()) {
117      ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
118      Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref);
119    }
120    return kHardFailure;
121  }
122  StackHandleScope<2> hs(self);
123  Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
124  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
125  return VerifyClass(self, &dex_file, dex_cache, class_loader, class_def, allow_soft_failures, error);
126}
127
128MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self,
129                                                        const DexFile* dex_file,
130                                                        Handle<mirror::DexCache> dex_cache,
131                                                        Handle<mirror::ClassLoader> class_loader,
132                                                        const DexFile::ClassDef* class_def,
133                                                        bool allow_soft_failures,
134                                                        std::string* error) {
135  DCHECK(class_def != nullptr);
136  const byte* class_data = dex_file->GetClassData(*class_def);
137  if (class_data == nullptr) {
138    // empty class, probably a marker interface
139    return kNoFailure;
140  }
141  ClassDataItemIterator it(*dex_file, class_data);
142  while (it.HasNextStaticField() || it.HasNextInstanceField()) {
143    it.Next();
144  }
145  size_t error_count = 0;
146  bool hard_fail = false;
147  ClassLinker* linker = Runtime::Current()->GetClassLinker();
148  int64_t previous_direct_method_idx = -1;
149  while (it.HasNextDirectMethod()) {
150    self->AllowThreadSuspension();
151    uint32_t method_idx = it.GetMemberIndex();
152    if (method_idx == previous_direct_method_idx) {
153      // smali can create dex files with two encoded_methods sharing the same method_idx
154      // http://code.google.com/p/smali/issues/detail?id=119
155      it.Next();
156      continue;
157    }
158    previous_direct_method_idx = method_idx;
159    InvokeType type = it.GetMethodInvokeType(*class_def);
160    mirror::ArtMethod* method =
161        linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
162                              NullHandle<mirror::ArtMethod>(), type);
163    if (method == nullptr) {
164      DCHECK(self->IsExceptionPending());
165      // We couldn't resolve the method, but continue regardless.
166      self->ClearException();
167    }
168    StackHandleScope<1> hs(self);
169    Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
170    MethodVerifier::FailureKind result = VerifyMethod(self,
171                                                      method_idx,
172                                                      dex_file,
173                                                      dex_cache,
174                                                      class_loader,
175                                                      class_def,
176                                                      it.GetMethodCodeItem(),
177                                                      h_method,
178                                                      it.GetMethodAccessFlags(),
179                                                      allow_soft_failures,
180                                                      false);
181    if (result != kNoFailure) {
182      if (result == kHardFailure) {
183        hard_fail = true;
184        if (error_count > 0) {
185          *error += "\n";
186        }
187        *error = "Verifier rejected class ";
188        *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
189        *error += " due to bad method ";
190        *error += PrettyMethod(method_idx, *dex_file);
191      }
192      ++error_count;
193    }
194    it.Next();
195  }
196  int64_t previous_virtual_method_idx = -1;
197  while (it.HasNextVirtualMethod()) {
198    self->AllowThreadSuspension();
199    uint32_t method_idx = it.GetMemberIndex();
200    if (method_idx == previous_virtual_method_idx) {
201      // smali can create dex files with two encoded_methods sharing the same method_idx
202      // http://code.google.com/p/smali/issues/detail?id=119
203      it.Next();
204      continue;
205    }
206    previous_virtual_method_idx = method_idx;
207    InvokeType type = it.GetMethodInvokeType(*class_def);
208    mirror::ArtMethod* method =
209        linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
210                              NullHandle<mirror::ArtMethod>(), type);
211    if (method == nullptr) {
212      DCHECK(self->IsExceptionPending());
213      // We couldn't resolve the method, but continue regardless.
214      self->ClearException();
215    }
216    StackHandleScope<1> hs(self);
217    Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
218    MethodVerifier::FailureKind result = VerifyMethod(self,
219                                                      method_idx,
220                                                      dex_file,
221                                                      dex_cache,
222                                                      class_loader,
223                                                      class_def,
224                                                      it.GetMethodCodeItem(),
225                                                      h_method,
226                                                      it.GetMethodAccessFlags(),
227                                                      allow_soft_failures,
228                                                      false);
229    if (result != kNoFailure) {
230      if (result == kHardFailure) {
231        hard_fail = true;
232        if (error_count > 0) {
233          *error += "\n";
234        }
235        *error = "Verifier rejected class ";
236        *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
237        *error += " due to bad method ";
238        *error += PrettyMethod(method_idx, *dex_file);
239      }
240      ++error_count;
241    }
242    it.Next();
243  }
244  if (error_count == 0) {
245    return kNoFailure;
246  } else {
247    return hard_fail ? kHardFailure : kSoftFailure;
248  }
249}
250
251MethodVerifier::FailureKind MethodVerifier::VerifyMethod(Thread* self, uint32_t method_idx,
252                                                         const DexFile* dex_file,
253                                                         Handle<mirror::DexCache> dex_cache,
254                                                         Handle<mirror::ClassLoader> class_loader,
255                                                         const DexFile::ClassDef* class_def,
256                                                         const DexFile::CodeItem* code_item,
257                                                         Handle<mirror::ArtMethod> method,
258                                                         uint32_t method_access_flags,
259                                                         bool allow_soft_failures,
260                                                         bool need_precise_constants) {
261  MethodVerifier::FailureKind result = kNoFailure;
262  uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0;
263
264  MethodVerifier verifier(self, dex_file, dex_cache, class_loader, class_def, code_item,
265                          method_idx, method, method_access_flags, true, allow_soft_failures,
266                          need_precise_constants);
267  if (verifier.Verify()) {
268    // Verification completed, however failures may be pending that didn't cause the verification
269    // to hard fail.
270    CHECK(!verifier.have_pending_hard_failure_);
271    if (verifier.failures_.size() != 0) {
272      if (VLOG_IS_ON(verifier)) {
273          verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in "
274                                << PrettyMethod(method_idx, *dex_file) << "\n");
275      }
276      result = kSoftFailure;
277    }
278  } else {
279    // Bad method data.
280    CHECK_NE(verifier.failures_.size(), 0U);
281    CHECK(verifier.have_pending_hard_failure_);
282    verifier.DumpFailures(LOG(INFO) << "Verification error in "
283                                    << PrettyMethod(method_idx, *dex_file) << "\n");
284    if (gDebugVerify) {
285      std::cout << "\n" << verifier.info_messages_.str();
286      verifier.Dump(std::cout);
287    }
288    result = kHardFailure;
289  }
290  if (kTimeVerifyMethod) {
291    uint64_t duration_ns = NanoTime() - start_ns;
292    if (duration_ns > MsToNs(100)) {
293      LOG(WARNING) << "Verification of " << PrettyMethod(method_idx, *dex_file)
294                   << " took " << PrettyDuration(duration_ns);
295    }
296  }
297  return result;
298}
299
300MethodVerifier* MethodVerifier::VerifyMethodAndDump(Thread* self, std::ostream& os, uint32_t dex_method_idx,
301                                         const DexFile* dex_file,
302                                         Handle<mirror::DexCache> dex_cache,
303                                         Handle<mirror::ClassLoader> class_loader,
304                                         const DexFile::ClassDef* class_def,
305                                         const DexFile::CodeItem* code_item,
306                                         Handle<mirror::ArtMethod> method,
307                                         uint32_t method_access_flags) {
308  MethodVerifier* verifier = new MethodVerifier(self, dex_file, dex_cache, class_loader,
309                                                class_def, code_item, dex_method_idx, method,
310                                                method_access_flags, true, true, true, true);
311  verifier->Verify();
312  verifier->DumpFailures(os);
313  os << verifier->info_messages_.str();
314  // Only dump and return if no hard failures. Otherwise the verifier may be not fully initialized
315  // and querying any info is dangerous/can abort.
316  if (verifier->have_pending_hard_failure_) {
317    delete verifier;
318    return nullptr;
319  } else {
320    verifier->Dump(os);
321    return verifier;
322  }
323}
324
325MethodVerifier::MethodVerifier(Thread* self,
326                               const DexFile* dex_file, Handle<mirror::DexCache> dex_cache,
327                               Handle<mirror::ClassLoader> class_loader,
328                               const DexFile::ClassDef* class_def,
329                               const DexFile::CodeItem* code_item, uint32_t dex_method_idx,
330                               Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
331                               bool can_load_classes, bool allow_soft_failures,
332                               bool need_precise_constants, bool verify_to_dump)
333    : self_(self),
334      reg_types_(can_load_classes),
335      work_insn_idx_(-1),
336      dex_method_idx_(dex_method_idx),
337      mirror_method_(method),
338      method_access_flags_(method_access_flags),
339      return_type_(nullptr),
340      dex_file_(dex_file),
341      dex_cache_(dex_cache),
342      class_loader_(class_loader),
343      class_def_(class_def),
344      code_item_(code_item),
345      declaring_class_(nullptr),
346      interesting_dex_pc_(-1),
347      monitor_enter_dex_pcs_(nullptr),
348      have_pending_hard_failure_(false),
349      have_pending_runtime_throw_failure_(false),
350      new_instance_count_(0),
351      monitor_enter_count_(0),
352      can_load_classes_(can_load_classes),
353      allow_soft_failures_(allow_soft_failures),
354      need_precise_constants_(need_precise_constants),
355      has_check_casts_(false),
356      has_virtual_or_interface_invokes_(false),
357      verify_to_dump_(verify_to_dump) {
358  Runtime::Current()->AddMethodVerifier(this);
359  DCHECK(class_def != nullptr);
360}
361
362MethodVerifier::~MethodVerifier() {
363  Runtime::Current()->RemoveMethodVerifier(this);
364  STLDeleteElements(&failure_messages_);
365}
366
367void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
368                                      std::vector<uint32_t>* monitor_enter_dex_pcs) {
369  Thread* self = Thread::Current();
370  StackHandleScope<3> hs(self);
371  Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
372  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
373  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
374  MethodVerifier verifier(self, m->GetDexFile(), dex_cache, class_loader, &m->GetClassDef(),
375                          m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
376                          false, true, false);
377  verifier.interesting_dex_pc_ = dex_pc;
378  verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
379  verifier.FindLocksAtDexPc();
380}
381
382void MethodVerifier::FindLocksAtDexPc() {
383  CHECK(monitor_enter_dex_pcs_ != nullptr);
384  CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
385
386  // Strictly speaking, we ought to be able to get away with doing a subset of the full method
387  // verification. In practice, the phase we want relies on data structures set up by all the
388  // earlier passes, so we just run the full method verification and bail out early when we've
389  // got what we wanted.
390  Verify();
391}
392
393mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
394                                                           uint32_t dex_pc) {
395  Thread* self = Thread::Current();
396  StackHandleScope<3> hs(self);
397  Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
398  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
399  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
400  MethodVerifier verifier(self, m->GetDexFile(), dex_cache, class_loader, &m->GetClassDef(),
401                          m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
402                          true, true, false);
403  return verifier.FindAccessedFieldAtDexPc(dex_pc);
404}
405
406mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) {
407  CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
408
409  // Strictly speaking, we ought to be able to get away with doing a subset of the full method
410  // verification. In practice, the phase we want relies on data structures set up by all the
411  // earlier passes, so we just run the full method verification and bail out early when we've
412  // got what we wanted.
413  bool success = Verify();
414  if (!success) {
415    return nullptr;
416  }
417  RegisterLine* register_line = reg_table_.GetLine(dex_pc);
418  if (register_line == nullptr) {
419    return nullptr;
420  }
421  const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
422  return GetQuickFieldAccess(inst, register_line);
423}
424
425mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m,
426                                                            uint32_t dex_pc) {
427  Thread* self = Thread::Current();
428  StackHandleScope<3> hs(self);
429  Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
430  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
431  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
432  MethodVerifier verifier(self, m->GetDexFile(), dex_cache, class_loader, &m->GetClassDef(),
433                          m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
434                          true, true, false);
435  return verifier.FindInvokedMethodAtDexPc(dex_pc);
436}
437
438mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(uint32_t dex_pc) {
439  CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
440
441  // Strictly speaking, we ought to be able to get away with doing a subset of the full method
442  // verification. In practice, the phase we want relies on data structures set up by all the
443  // earlier passes, so we just run the full method verification and bail out early when we've
444  // got what we wanted.
445  bool success = Verify();
446  if (!success) {
447    return nullptr;
448  }
449  RegisterLine* register_line = reg_table_.GetLine(dex_pc);
450  if (register_line == nullptr) {
451    return nullptr;
452  }
453  const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
454  const bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
455  return GetQuickInvokedMethod(inst, register_line, is_range);
456}
457
458bool MethodVerifier::Verify() {
459  // If there aren't any instructions, make sure that's expected, then exit successfully.
460  if (code_item_ == nullptr) {
461    if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) {
462      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method";
463      return false;
464    } else {
465      return true;
466    }
467  }
468  // Sanity-check the register counts. ins + locals = registers, so make sure that ins <= registers.
469  if (code_item_->ins_size_ > code_item_->registers_size_) {
470    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins=" << code_item_->ins_size_
471                                      << " regs=" << code_item_->registers_size_;
472    return false;
473  }
474  // Allocate and initialize an array to hold instruction data.
475  insn_flags_.reset(new InstructionFlags[code_item_->insns_size_in_code_units_]());
476  // Run through the instructions and see if the width checks out.
477  bool result = ComputeWidthsAndCountOps();
478  // Flag instructions guarded by a "try" block and check exception handlers.
479  result = result && ScanTryCatchBlocks();
480  // Perform static instruction verification.
481  result = result && VerifyInstructions();
482  // Perform code-flow analysis and return.
483  result = result && VerifyCodeFlow();
484  // Compute information for compiler.
485  if (result && Runtime::Current()->IsCompiler()) {
486    result = Runtime::Current()->GetCompilerCallbacks()->MethodVerified(this);
487  }
488  return result;
489}
490
491std::ostream& MethodVerifier::Fail(VerifyError error) {
492  switch (error) {
493    case VERIFY_ERROR_NO_CLASS:
494    case VERIFY_ERROR_NO_FIELD:
495    case VERIFY_ERROR_NO_METHOD:
496    case VERIFY_ERROR_ACCESS_CLASS:
497    case VERIFY_ERROR_ACCESS_FIELD:
498    case VERIFY_ERROR_ACCESS_METHOD:
499    case VERIFY_ERROR_INSTANTIATION:
500    case VERIFY_ERROR_CLASS_CHANGE:
501      if (Runtime::Current()->IsCompiler() || !can_load_classes_) {
502        // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx,
503        // class change and instantiation errors into soft verification errors so that we re-verify
504        // at runtime. We may fail to find or to agree on access because of not yet available class
505        // loaders, or class loaders that will differ at runtime. In these cases, we don't want to
506        // affect the soundness of the code being compiled. Instead, the generated code runs "slow
507        // paths" that dynamically perform the verification and cause the behavior to be that akin
508        // to an interpreter.
509        error = VERIFY_ERROR_BAD_CLASS_SOFT;
510      } else {
511        // If we fail again at runtime, mark that this instruction would throw and force this
512        // method to be executed using the interpreter with checks.
513        have_pending_runtime_throw_failure_ = true;
514      }
515      break;
516      // Indication that verification should be retried at runtime.
517    case VERIFY_ERROR_BAD_CLASS_SOFT:
518      if (!allow_soft_failures_) {
519        have_pending_hard_failure_ = true;
520      }
521      break;
522      // Hard verification failures at compile time will still fail at runtime, so the class is
523      // marked as rejected to prevent it from being compiled.
524    case VERIFY_ERROR_BAD_CLASS_HARD: {
525      if (Runtime::Current()->IsCompiler()) {
526        ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_));
527        Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref);
528      }
529      have_pending_hard_failure_ = true;
530      break;
531    }
532  }
533  failures_.push_back(error);
534  std::string location(StringPrintf("%s: [0x%X] ", PrettyMethod(dex_method_idx_, *dex_file_).c_str(),
535                                    work_insn_idx_));
536  std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate);
537  failure_messages_.push_back(failure_message);
538  return *failure_message;
539}
540
541std::ostream& MethodVerifier::LogVerifyInfo() {
542  return info_messages_ << "VFY: " << PrettyMethod(dex_method_idx_, *dex_file_)
543                        << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
544}
545
546void MethodVerifier::PrependToLastFailMessage(std::string prepend) {
547  size_t failure_num = failure_messages_.size();
548  DCHECK_NE(failure_num, 0U);
549  std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
550  prepend += last_fail_message->str();
551  failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate);
552  delete last_fail_message;
553}
554
555void MethodVerifier::AppendToLastFailMessage(std::string append) {
556  size_t failure_num = failure_messages_.size();
557  DCHECK_NE(failure_num, 0U);
558  std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
559  (*last_fail_message) << append;
560}
561
562bool MethodVerifier::ComputeWidthsAndCountOps() {
563  const uint16_t* insns = code_item_->insns_;
564  size_t insns_size = code_item_->insns_size_in_code_units_;
565  const Instruction* inst = Instruction::At(insns);
566  size_t new_instance_count = 0;
567  size_t monitor_enter_count = 0;
568  size_t dex_pc = 0;
569
570  while (dex_pc < insns_size) {
571    Instruction::Code opcode = inst->Opcode();
572    switch (opcode) {
573      case Instruction::APUT_OBJECT:
574      case Instruction::CHECK_CAST:
575        has_check_casts_ = true;
576        break;
577      case Instruction::INVOKE_VIRTUAL:
578      case Instruction::INVOKE_VIRTUAL_RANGE:
579      case Instruction::INVOKE_INTERFACE:
580      case Instruction::INVOKE_INTERFACE_RANGE:
581        has_virtual_or_interface_invokes_ = true;
582        break;
583      case Instruction::MONITOR_ENTER:
584        monitor_enter_count++;
585        break;
586      case Instruction::NEW_INSTANCE:
587        new_instance_count++;
588        break;
589      default:
590        break;
591    }
592    size_t inst_size = inst->SizeInCodeUnits();
593    insn_flags_[dex_pc].SetIsOpcode();
594    dex_pc += inst_size;
595    inst = inst->RelativeAt(inst_size);
596  }
597
598  if (dex_pc != insns_size) {
599    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected ("
600                                      << dex_pc << " vs. " << insns_size << ")";
601    return false;
602  }
603
604  new_instance_count_ = new_instance_count;
605  monitor_enter_count_ = monitor_enter_count;
606  return true;
607}
608
609bool MethodVerifier::ScanTryCatchBlocks() {
610  uint32_t tries_size = code_item_->tries_size_;
611  if (tries_size == 0) {
612    return true;
613  }
614  uint32_t insns_size = code_item_->insns_size_in_code_units_;
615  const DexFile::TryItem* tries = DexFile::GetTryItems(*code_item_, 0);
616
617  for (uint32_t idx = 0; idx < tries_size; idx++) {
618    const DexFile::TryItem* try_item = &tries[idx];
619    uint32_t start = try_item->start_addr_;
620    uint32_t end = start + try_item->insn_count_;
621    if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
622      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start
623                                        << " endAddr=" << end << " (size=" << insns_size << ")";
624      return false;
625    }
626    if (!insn_flags_[start].IsOpcode()) {
627      Fail(VERIFY_ERROR_BAD_CLASS_HARD)
628          << "'try' block starts inside an instruction (" << start << ")";
629      return false;
630    }
631    uint32_t dex_pc = start;
632    const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
633    while (dex_pc < end) {
634      insn_flags_[dex_pc].SetInTry();
635      size_t insn_size = inst->SizeInCodeUnits();
636      dex_pc += insn_size;
637      inst = inst->RelativeAt(insn_size);
638    }
639  }
640  // Iterate over each of the handlers to verify target addresses.
641  const byte* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
642  uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
643  ClassLinker* linker = Runtime::Current()->GetClassLinker();
644  for (uint32_t idx = 0; idx < handlers_size; idx++) {
645    CatchHandlerIterator iterator(handlers_ptr);
646    for (; iterator.HasNext(); iterator.Next()) {
647      uint32_t dex_pc= iterator.GetHandlerAddress();
648      if (!insn_flags_[dex_pc].IsOpcode()) {
649        Fail(VERIFY_ERROR_BAD_CLASS_HARD)
650            << "exception handler starts at bad address (" << dex_pc << ")";
651        return false;
652      }
653      insn_flags_[dex_pc].SetBranchTarget();
654      // Ensure exception types are resolved so that they don't need resolution to be delivered,
655      // unresolved exception types will be ignored by exception delivery
656      if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) {
657        mirror::Class* exception_type = linker->ResolveType(*dex_file_,
658                                                            iterator.GetHandlerTypeIndex(),
659                                                            dex_cache_, class_loader_);
660        if (exception_type == nullptr) {
661          DCHECK(self_->IsExceptionPending());
662          self_->ClearException();
663        }
664      }
665    }
666    handlers_ptr = iterator.EndDataPointer();
667  }
668  return true;
669}
670
671bool MethodVerifier::VerifyInstructions() {
672  const Instruction* inst = Instruction::At(code_item_->insns_);
673
674  /* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */
675  insn_flags_[0].SetBranchTarget();
676  insn_flags_[0].SetCompileTimeInfoPoint();
677
678  uint32_t insns_size = code_item_->insns_size_in_code_units_;
679  for (uint32_t dex_pc = 0; dex_pc < insns_size;) {
680    if (!VerifyInstruction(inst, dex_pc)) {
681      DCHECK_NE(failures_.size(), 0U);
682      return false;
683    }
684    /* Flag instructions that are garbage collection points */
685    // All invoke points are marked as "Throw" points already.
686    // We are relying on this to also count all the invokes as interesting.
687    if (inst->IsBranch() || inst->IsSwitch() || inst->IsThrow()) {
688      insn_flags_[dex_pc].SetCompileTimeInfoPoint();
689    } else if (inst->IsReturn()) {
690      insn_flags_[dex_pc].SetCompileTimeInfoPointAndReturn();
691    }
692    dex_pc += inst->SizeInCodeUnits();
693    inst = inst->Next();
694  }
695  return true;
696}
697
698bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_offset) {
699  bool result = true;
700  switch (inst->GetVerifyTypeArgumentA()) {
701    case Instruction::kVerifyRegA:
702      result = result && CheckRegisterIndex(inst->VRegA());
703      break;
704    case Instruction::kVerifyRegAWide:
705      result = result && CheckWideRegisterIndex(inst->VRegA());
706      break;
707  }
708  switch (inst->GetVerifyTypeArgumentB()) {
709    case Instruction::kVerifyRegB:
710      result = result && CheckRegisterIndex(inst->VRegB());
711      break;
712    case Instruction::kVerifyRegBField:
713      result = result && CheckFieldIndex(inst->VRegB());
714      break;
715    case Instruction::kVerifyRegBMethod:
716      result = result && CheckMethodIndex(inst->VRegB());
717      break;
718    case Instruction::kVerifyRegBNewInstance:
719      result = result && CheckNewInstance(inst->VRegB());
720      break;
721    case Instruction::kVerifyRegBString:
722      result = result && CheckStringIndex(inst->VRegB());
723      break;
724    case Instruction::kVerifyRegBType:
725      result = result && CheckTypeIndex(inst->VRegB());
726      break;
727    case Instruction::kVerifyRegBWide:
728      result = result && CheckWideRegisterIndex(inst->VRegB());
729      break;
730  }
731  switch (inst->GetVerifyTypeArgumentC()) {
732    case Instruction::kVerifyRegC:
733      result = result && CheckRegisterIndex(inst->VRegC());
734      break;
735    case Instruction::kVerifyRegCField:
736      result = result && CheckFieldIndex(inst->VRegC());
737      break;
738    case Instruction::kVerifyRegCNewArray:
739      result = result && CheckNewArray(inst->VRegC());
740      break;
741    case Instruction::kVerifyRegCType:
742      result = result && CheckTypeIndex(inst->VRegC());
743      break;
744    case Instruction::kVerifyRegCWide:
745      result = result && CheckWideRegisterIndex(inst->VRegC());
746      break;
747  }
748  switch (inst->GetVerifyExtraFlags()) {
749    case Instruction::kVerifyArrayData:
750      result = result && CheckArrayData(code_offset);
751      break;
752    case Instruction::kVerifyBranchTarget:
753      result = result && CheckBranchTarget(code_offset);
754      break;
755    case Instruction::kVerifySwitchTargets:
756      result = result && CheckSwitchTargets(code_offset);
757      break;
758    case Instruction::kVerifyVarArgNonZero:
759      // Fall-through.
760    case Instruction::kVerifyVarArg: {
761      if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && inst->VRegA() <= 0) {
762        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
763                                             "non-range invoke";
764        return false;
765      }
766      uint32_t args[Instruction::kMaxVarArgRegs];
767      inst->GetVarArgs(args);
768      result = result && CheckVarArgRegs(inst->VRegA(), args);
769      break;
770    }
771    case Instruction::kVerifyVarArgRangeNonZero:
772      // Fall-through.
773    case Instruction::kVerifyVarArgRange:
774      if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero &&
775          inst->VRegA() <= 0) {
776        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
777                                             "range invoke";
778        return false;
779      }
780      result = result && CheckVarArgRangeRegs(inst->VRegA(), inst->VRegC());
781      break;
782    case Instruction::kVerifyError:
783      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name();
784      result = false;
785      break;
786  }
787  if (inst->GetVerifyIsRuntimeOnly() && Runtime::Current()->IsCompiler() && !verify_to_dump_) {
788    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "opcode only expected at runtime " << inst->Name();
789    result = false;
790  }
791  return result;
792}
793
794inline bool MethodVerifier::CheckRegisterIndex(uint32_t idx) {
795  if (idx >= code_item_->registers_size_) {
796    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= "
797                                      << code_item_->registers_size_ << ")";
798    return false;
799  }
800  return true;
801}
802
803inline bool MethodVerifier::CheckWideRegisterIndex(uint32_t idx) {
804  if (idx + 1 >= code_item_->registers_size_) {
805    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx
806                                      << "+1 >= " << code_item_->registers_size_ << ")";
807    return false;
808  }
809  return true;
810}
811
812inline bool MethodVerifier::CheckFieldIndex(uint32_t idx) {
813  if (idx >= dex_file_->GetHeader().field_ids_size_) {
814    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad field index " << idx << " (max "
815                                      << dex_file_->GetHeader().field_ids_size_ << ")";
816    return false;
817  }
818  return true;
819}
820
821inline bool MethodVerifier::CheckMethodIndex(uint32_t idx) {
822  if (idx >= dex_file_->GetHeader().method_ids_size_) {
823    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method index " << idx << " (max "
824                                      << dex_file_->GetHeader().method_ids_size_ << ")";
825    return false;
826  }
827  return true;
828}
829
830inline bool MethodVerifier::CheckNewInstance(uint32_t idx) {
831  if (idx >= dex_file_->GetHeader().type_ids_size_) {
832    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max "
833                                      << dex_file_->GetHeader().type_ids_size_ << ")";
834    return false;
835  }
836  // We don't need the actual class, just a pointer to the class name.
837  const char* descriptor = dex_file_->StringByTypeIdx(idx);
838  if (descriptor[0] != 'L') {
839    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'";
840    return false;
841  }
842  return true;
843}
844
845inline bool MethodVerifier::CheckStringIndex(uint32_t idx) {
846  if (idx >= dex_file_->GetHeader().string_ids_size_) {
847    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max "
848                                      << dex_file_->GetHeader().string_ids_size_ << ")";
849    return false;
850  }
851  return true;
852}
853
854inline bool MethodVerifier::CheckTypeIndex(uint32_t idx) {
855  if (idx >= dex_file_->GetHeader().type_ids_size_) {
856    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max "
857                                      << dex_file_->GetHeader().type_ids_size_ << ")";
858    return false;
859  }
860  return true;
861}
862
863bool MethodVerifier::CheckNewArray(uint32_t idx) {
864  if (idx >= dex_file_->GetHeader().type_ids_size_) {
865    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max "
866                                      << dex_file_->GetHeader().type_ids_size_ << ")";
867    return false;
868  }
869  int bracket_count = 0;
870  const char* descriptor = dex_file_->StringByTypeIdx(idx);
871  const char* cp = descriptor;
872  while (*cp++ == '[') {
873    bracket_count++;
874  }
875  if (bracket_count == 0) {
876    /* The given class must be an array type. */
877    Fail(VERIFY_ERROR_BAD_CLASS_HARD)
878        << "can't new-array class '" << descriptor << "' (not an array)";
879    return false;
880  } else if (bracket_count > 255) {
881    /* It is illegal to create an array of more than 255 dimensions. */
882    Fail(VERIFY_ERROR_BAD_CLASS_HARD)
883        << "can't new-array class '" << descriptor << "' (exceeds limit)";
884    return false;
885  }
886  return true;
887}
888
889bool MethodVerifier::CheckArrayData(uint32_t cur_offset) {
890  const uint32_t insn_count = code_item_->insns_size_in_code_units_;
891  const uint16_t* insns = code_item_->insns_ + cur_offset;
892  const uint16_t* array_data;
893  int32_t array_data_offset;
894
895  DCHECK_LT(cur_offset, insn_count);
896  /* make sure the start of the array data table is in range */
897  array_data_offset = insns[1] | (((int32_t) insns[2]) << 16);
898  if ((int32_t) cur_offset + array_data_offset < 0 ||
899      cur_offset + array_data_offset + 2 >= insn_count) {
900    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset
901                                      << ", data offset " << array_data_offset
902                                      << ", count " << insn_count;
903    return false;
904  }
905  /* offset to array data table is a relative branch-style offset */
906  array_data = insns + array_data_offset;
907  /* make sure the table is 32-bit aligned */
908  if ((reinterpret_cast<uintptr_t>(array_data) & 0x03) != 0) {
909    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset
910                                      << ", data offset " << array_data_offset;
911    return false;
912  }
913  uint32_t value_width = array_data[1];
914  uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]);
915  uint32_t table_size = 4 + (value_width * value_count + 1) / 2;
916  /* make sure the end of the switch is in range */
917  if (cur_offset + array_data_offset + table_size > insn_count) {
918    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset
919                                      << ", data offset " << array_data_offset << ", end "
920                                      << cur_offset + array_data_offset + table_size
921                                      << ", count " << insn_count;
922    return false;
923  }
924  return true;
925}
926
927bool MethodVerifier::CheckBranchTarget(uint32_t cur_offset) {
928  int32_t offset;
929  bool isConditional, selfOkay;
930  if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) {
931    return false;
932  }
933  if (!selfOkay && offset == 0) {
934    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at"
935                                      << reinterpret_cast<void*>(cur_offset);
936    return false;
937  }
938  // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime
939  // to have identical "wrap-around" behavior, but it's unwise to depend on that.
940  if (((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset)) {
941    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow "
942                                      << reinterpret_cast<void*>(cur_offset) << " +" << offset;
943    return false;
944  }
945  const uint32_t insn_count = code_item_->insns_size_in_code_units_;
946  int32_t abs_offset = cur_offset + offset;
947  if (abs_offset < 0 ||
948      (uint32_t) abs_offset >= insn_count ||
949      !insn_flags_[abs_offset].IsOpcode()) {
950    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> "
951                                      << reinterpret_cast<void*>(abs_offset) << ") at "
952                                      << reinterpret_cast<void*>(cur_offset);
953    return false;
954  }
955  insn_flags_[abs_offset].SetBranchTarget();
956  return true;
957}
958
959bool MethodVerifier::GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional,
960                                  bool* selfOkay) {
961  const uint16_t* insns = code_item_->insns_ + cur_offset;
962  *pConditional = false;
963  *selfOkay = false;
964  switch (*insns & 0xff) {
965    case Instruction::GOTO:
966      *pOffset = ((int16_t) *insns) >> 8;
967      break;
968    case Instruction::GOTO_32:
969      *pOffset = insns[1] | (((uint32_t) insns[2]) << 16);
970      *selfOkay = true;
971      break;
972    case Instruction::GOTO_16:
973      *pOffset = (int16_t) insns[1];
974      break;
975    case Instruction::IF_EQ:
976    case Instruction::IF_NE:
977    case Instruction::IF_LT:
978    case Instruction::IF_GE:
979    case Instruction::IF_GT:
980    case Instruction::IF_LE:
981    case Instruction::IF_EQZ:
982    case Instruction::IF_NEZ:
983    case Instruction::IF_LTZ:
984    case Instruction::IF_GEZ:
985    case Instruction::IF_GTZ:
986    case Instruction::IF_LEZ:
987      *pOffset = (int16_t) insns[1];
988      *pConditional = true;
989      break;
990    default:
991      return false;
992      break;
993  }
994  return true;
995}
996
997bool MethodVerifier::CheckSwitchTargets(uint32_t cur_offset) {
998  const uint32_t insn_count = code_item_->insns_size_in_code_units_;
999  DCHECK_LT(cur_offset, insn_count);
1000  const uint16_t* insns = code_item_->insns_ + cur_offset;
1001  /* make sure the start of the switch is in range */
1002  int32_t switch_offset = insns[1] | ((int32_t) insns[2]) << 16;
1003  if ((int32_t) cur_offset + switch_offset < 0 || cur_offset + switch_offset + 2 >= insn_count) {
1004    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset
1005                                      << ", switch offset " << switch_offset
1006                                      << ", count " << insn_count;
1007    return false;
1008  }
1009  /* offset to switch table is a relative branch-style offset */
1010  const uint16_t* switch_insns = insns + switch_offset;
1011  /* make sure the table is 32-bit aligned */
1012  if ((reinterpret_cast<uintptr_t>(switch_insns) & 0x03) != 0) {
1013    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset
1014                                      << ", switch offset " << switch_offset;
1015    return false;
1016  }
1017  uint32_t switch_count = switch_insns[1];
1018  int32_t keys_offset, targets_offset;
1019  uint16_t expected_signature;
1020  if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
1021    /* 0=sig, 1=count, 2/3=firstKey */
1022    targets_offset = 4;
1023    keys_offset = -1;
1024    expected_signature = Instruction::kPackedSwitchSignature;
1025  } else {
1026    /* 0=sig, 1=count, 2..count*2 = keys */
1027    keys_offset = 2;
1028    targets_offset = 2 + 2 * switch_count;
1029    expected_signature = Instruction::kSparseSwitchSignature;
1030  }
1031  uint32_t table_size = targets_offset + switch_count * 2;
1032  if (switch_insns[0] != expected_signature) {
1033    Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1034        << StringPrintf("wrong signature for switch table (%x, wanted %x)",
1035                        switch_insns[0], expected_signature);
1036    return false;
1037  }
1038  /* make sure the end of the switch is in range */
1039  if (cur_offset + switch_offset + table_size > (uint32_t) insn_count) {
1040    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset
1041                                      << ", switch offset " << switch_offset
1042                                      << ", end " << (cur_offset + switch_offset + table_size)
1043                                      << ", count " << insn_count;
1044    return false;
1045  }
1046  /* for a sparse switch, verify the keys are in ascending order */
1047  if (keys_offset > 0 && switch_count > 1) {
1048    int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
1049    for (uint32_t targ = 1; targ < switch_count; targ++) {
1050      int32_t key = (int32_t) switch_insns[keys_offset + targ * 2] |
1051                    (int32_t) (switch_insns[keys_offset + targ * 2 + 1] << 16);
1052      if (key <= last_key) {
1053        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: last key=" << last_key
1054                                          << ", this=" << key;
1055        return false;
1056      }
1057      last_key = key;
1058    }
1059  }
1060  /* verify each switch target */
1061  for (uint32_t targ = 0; targ < switch_count; targ++) {
1062    int32_t offset = (int32_t) switch_insns[targets_offset + targ * 2] |
1063                     (int32_t) (switch_insns[targets_offset + targ * 2 + 1] << 16);
1064    int32_t abs_offset = cur_offset + offset;
1065    if (abs_offset < 0 ||
1066        abs_offset >= (int32_t) insn_count ||
1067        !insn_flags_[abs_offset].IsOpcode()) {
1068      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset
1069                                        << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at "
1070                                        << reinterpret_cast<void*>(cur_offset)
1071                                        << "[" << targ << "]";
1072      return false;
1073    }
1074    insn_flags_[abs_offset].SetBranchTarget();
1075  }
1076  return true;
1077}
1078
1079bool MethodVerifier::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) {
1080  if (vA > Instruction::kMaxVarArgRegs) {
1081    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << vA << ") in non-range invoke)";
1082    return false;
1083  }
1084  uint16_t registers_size = code_item_->registers_size_;
1085  for (uint32_t idx = 0; idx < vA; idx++) {
1086    if (arg[idx] >= registers_size) {
1087      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index (" << arg[idx]
1088                                        << ") in non-range invoke (>= " << registers_size << ")";
1089      return false;
1090    }
1091  }
1092
1093  return true;
1094}
1095
1096bool MethodVerifier::CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) {
1097  uint16_t registers_size = code_item_->registers_size_;
1098  // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of
1099  // integer overflow when adding them here.
1100  if (vA + vC > registers_size) {
1101    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC
1102                                      << " in range invoke (> " << registers_size << ")";
1103    return false;
1104  }
1105  return true;
1106}
1107
1108bool MethodVerifier::VerifyCodeFlow() {
1109  uint16_t registers_size = code_item_->registers_size_;
1110  uint32_t insns_size = code_item_->insns_size_in_code_units_;
1111
1112  if (registers_size * insns_size > 4*1024*1024) {
1113    LOG(WARNING) << "warning: method is huge (regs=" << registers_size
1114                 << " insns_size=" << insns_size << ")";
1115  }
1116  /* Create and initialize table holding register status */
1117  reg_table_.Init(kTrackCompilerInterestPoints,
1118                  insn_flags_.get(),
1119                  insns_size,
1120                  registers_size,
1121                  this);
1122
1123
1124  work_line_.reset(RegisterLine::Create(registers_size, this));
1125  saved_line_.reset(RegisterLine::Create(registers_size, this));
1126
1127  /* Initialize register types of method arguments. */
1128  if (!SetTypesFromSignature()) {
1129    DCHECK_NE(failures_.size(), 0U);
1130    std::string prepend("Bad signature in ");
1131    prepend += PrettyMethod(dex_method_idx_, *dex_file_);
1132    PrependToLastFailMessage(prepend);
1133    return false;
1134  }
1135  /* Perform code flow verification. */
1136  if (!CodeFlowVerifyMethod()) {
1137    DCHECK_NE(failures_.size(), 0U);
1138    return false;
1139  }
1140  return true;
1141}
1142
1143std::ostream& MethodVerifier::DumpFailures(std::ostream& os) {
1144  DCHECK_EQ(failures_.size(), failure_messages_.size());
1145  for (size_t i = 0; i < failures_.size(); ++i) {
1146      os << failure_messages_[i]->str() << "\n";
1147  }
1148  return os;
1149}
1150
1151extern "C" void MethodVerifierGdbDump(MethodVerifier* v)
1152    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1153  v->Dump(std::cerr);
1154}
1155
1156void MethodVerifier::Dump(std::ostream& os) {
1157  if (code_item_ == nullptr) {
1158    os << "Native method\n";
1159    return;
1160  }
1161  {
1162    os << "Register Types:\n";
1163    Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
1164    std::ostream indent_os(&indent_filter);
1165    reg_types_.Dump(indent_os);
1166  }
1167  os << "Dumping instructions and register lines:\n";
1168  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
1169  std::ostream indent_os(&indent_filter);
1170  const Instruction* inst = Instruction::At(code_item_->insns_);
1171  for (size_t dex_pc = 0; dex_pc < code_item_->insns_size_in_code_units_;
1172      dex_pc += inst->SizeInCodeUnits()) {
1173    RegisterLine* reg_line = reg_table_.GetLine(dex_pc);
1174    if (reg_line != nullptr) {
1175      indent_os << reg_line->Dump(this) << "\n";
1176    }
1177    indent_os << StringPrintf("0x%04zx", dex_pc) << ": " << insn_flags_[dex_pc].ToString() << " ";
1178    const bool kDumpHexOfInstruction = false;
1179    if (kDumpHexOfInstruction) {
1180      indent_os << inst->DumpHex(5) << " ";
1181    }
1182    indent_os << inst->DumpString(dex_file_) << "\n";
1183    inst = inst->Next();
1184  }
1185}
1186
1187static bool IsPrimitiveDescriptor(char descriptor) {
1188  switch (descriptor) {
1189    case 'I':
1190    case 'C':
1191    case 'S':
1192    case 'B':
1193    case 'Z':
1194    case 'F':
1195    case 'D':
1196    case 'J':
1197      return true;
1198    default:
1199      return false;
1200  }
1201}
1202
1203bool MethodVerifier::SetTypesFromSignature() {
1204  RegisterLine* reg_line = reg_table_.GetLine(0);
1205  int arg_start = code_item_->registers_size_ - code_item_->ins_size_;
1206  size_t expected_args = code_item_->ins_size_;   /* long/double count as two */
1207
1208  DCHECK_GE(arg_start, 0);      /* should have been verified earlier */
1209  // Include the "this" pointer.
1210  size_t cur_arg = 0;
1211  if (!IsStatic()) {
1212    // If this is a constructor for a class other than java.lang.Object, mark the first ("this")
1213    // argument as uninitialized. This restricts field access until the superclass constructor is
1214    // called.
1215    const RegType& declaring_class = GetDeclaringClass();
1216    if (IsConstructor() && !declaring_class.IsJavaLangObject()) {
1217      reg_line->SetRegisterType(this, arg_start + cur_arg,
1218                                reg_types_.UninitializedThisArgument(declaring_class));
1219    } else {
1220      reg_line->SetRegisterType(this, arg_start + cur_arg, declaring_class);
1221    }
1222    cur_arg++;
1223  }
1224
1225  const DexFile::ProtoId& proto_id =
1226      dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
1227  DexFileParameterIterator iterator(*dex_file_, proto_id);
1228
1229  for (; iterator.HasNext(); iterator.Next()) {
1230    const char* descriptor = iterator.GetDescriptor();
1231    if (descriptor == nullptr) {
1232      LOG(FATAL) << "Null descriptor";
1233    }
1234    if (cur_arg >= expected_args) {
1235      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
1236                                        << " args, found more (" << descriptor << ")";
1237      return false;
1238    }
1239    switch (descriptor[0]) {
1240      case 'L':
1241      case '[':
1242        // We assume that reference arguments are initialized. The only way it could be otherwise
1243        // (assuming the caller was verified) is if the current method is <init>, but in that case
1244        // it's effectively considered initialized the instant we reach here (in the sense that we
1245        // can return without doing anything or call virtual methods).
1246        {
1247          const RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx());
1248          if (!reg_type.IsNonZeroReferenceTypes()) {
1249            DCHECK(HasFailures());
1250            return false;
1251          }
1252          reg_line->SetRegisterType(this, arg_start + cur_arg, reg_type);
1253        }
1254        break;
1255      case 'Z':
1256        reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Boolean());
1257        break;
1258      case 'C':
1259        reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Char());
1260        break;
1261      case 'B':
1262        reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Byte());
1263        break;
1264      case 'I':
1265        reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Integer());
1266        break;
1267      case 'S':
1268        reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Short());
1269        break;
1270      case 'F':
1271        reg_line->SetRegisterType(this, arg_start + cur_arg, reg_types_.Float());
1272        break;
1273      case 'J':
1274      case 'D': {
1275        if (cur_arg + 1 >= expected_args) {
1276          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
1277              << " args, found more (" << descriptor << ")";
1278          return false;
1279        }
1280
1281        const RegType* lo_half;
1282        const RegType* hi_half;
1283        if (descriptor[0] == 'J') {
1284          lo_half = &reg_types_.LongLo();
1285          hi_half = &reg_types_.LongHi();
1286        } else {
1287          lo_half = &reg_types_.DoubleLo();
1288          hi_half = &reg_types_.DoubleHi();
1289        }
1290        reg_line->SetRegisterTypeWide(this, arg_start + cur_arg, *lo_half, *hi_half);
1291        cur_arg++;
1292        break;
1293      }
1294      default:
1295        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '"
1296                                          << descriptor << "'";
1297        return false;
1298    }
1299    cur_arg++;
1300  }
1301  if (cur_arg != expected_args) {
1302    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
1303                                      << " arguments, found " << cur_arg;
1304    return false;
1305  }
1306  const char* descriptor = dex_file_->GetReturnTypeDescriptor(proto_id);
1307  // Validate return type. We don't do the type lookup; just want to make sure that it has the right
1308  // format. Only major difference from the method argument format is that 'V' is supported.
1309  bool result;
1310  if (IsPrimitiveDescriptor(descriptor[0]) || descriptor[0] == 'V') {
1311    result = descriptor[1] == '\0';
1312  } else if (descriptor[0] == '[') {  // single/multi-dimensional array of object/primitive
1313    size_t i = 0;
1314    do {
1315      i++;
1316    } while (descriptor[i] == '[');  // process leading [
1317    if (descriptor[i] == 'L') {  // object array
1318      do {
1319        i++;  // find closing ;
1320      } while (descriptor[i] != ';' && descriptor[i] != '\0');
1321      result = descriptor[i] == ';';
1322    } else {  // primitive array
1323      result = IsPrimitiveDescriptor(descriptor[i]) && descriptor[i + 1] == '\0';
1324    }
1325  } else if (descriptor[0] == 'L') {
1326    // could be more thorough here, but shouldn't be required
1327    size_t i = 0;
1328    do {
1329      i++;
1330    } while (descriptor[i] != ';' && descriptor[i] != '\0');
1331    result = descriptor[i] == ';';
1332  } else {
1333    result = false;
1334  }
1335  if (!result) {
1336    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected char in return type descriptor '"
1337                                      << descriptor << "'";
1338  }
1339  return result;
1340}
1341
1342bool MethodVerifier::CodeFlowVerifyMethod() {
1343  const uint16_t* insns = code_item_->insns_;
1344  const uint32_t insns_size = code_item_->insns_size_in_code_units_;
1345
1346  /* Begin by marking the first instruction as "changed". */
1347  insn_flags_[0].SetChanged();
1348  uint32_t start_guess = 0;
1349
1350  /* Continue until no instructions are marked "changed". */
1351  while (true) {
1352    self_->AllowThreadSuspension();
1353    // Find the first marked one. Use "start_guess" as a way to find one quickly.
1354    uint32_t insn_idx = start_guess;
1355    for (; insn_idx < insns_size; insn_idx++) {
1356      if (insn_flags_[insn_idx].IsChanged())
1357        break;
1358    }
1359    if (insn_idx == insns_size) {
1360      if (start_guess != 0) {
1361        /* try again, starting from the top */
1362        start_guess = 0;
1363        continue;
1364      } else {
1365        /* all flags are clear */
1366        break;
1367      }
1368    }
1369    // We carry the working set of registers from instruction to instruction. If this address can
1370    // be the target of a branch (or throw) instruction, or if we're skipping around chasing
1371    // "changed" flags, we need to load the set of registers from the table.
1372    // Because we always prefer to continue on to the next instruction, we should never have a
1373    // situation where we have a stray "changed" flag set on an instruction that isn't a branch
1374    // target.
1375    work_insn_idx_ = insn_idx;
1376    if (insn_flags_[insn_idx].IsBranchTarget()) {
1377      work_line_->CopyFromLine(reg_table_.GetLine(insn_idx));
1378    } else if (kIsDebugBuild) {
1379      /*
1380       * Sanity check: retrieve the stored register line (assuming
1381       * a full table) and make sure it actually matches.
1382       */
1383      RegisterLine* register_line = reg_table_.GetLine(insn_idx);
1384      if (register_line != nullptr) {
1385        if (work_line_->CompareLine(register_line) != 0) {
1386          Dump(std::cout);
1387          std::cout << info_messages_.str();
1388          LOG(FATAL) << "work_line diverged in " << PrettyMethod(dex_method_idx_, *dex_file_)
1389                     << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n"
1390                     << " work_line=" << work_line_->Dump(this) << "\n"
1391                     << "  expected=" << register_line->Dump(this);
1392        }
1393      }
1394    }
1395    if (!CodeFlowVerifyInstruction(&start_guess)) {
1396      std::string prepend(PrettyMethod(dex_method_idx_, *dex_file_));
1397      prepend += " failed to verify: ";
1398      PrependToLastFailMessage(prepend);
1399      return false;
1400    }
1401    /* Clear "changed" and mark as visited. */
1402    insn_flags_[insn_idx].SetVisited();
1403    insn_flags_[insn_idx].ClearChanged();
1404  }
1405
1406  if (gDebugVerify) {
1407    /*
1408     * Scan for dead code. There's nothing "evil" about dead code
1409     * (besides the wasted space), but it indicates a flaw somewhere
1410     * down the line, possibly in the verifier.
1411     *
1412     * If we've substituted "always throw" instructions into the stream,
1413     * we are almost certainly going to have some dead code.
1414     */
1415    int dead_start = -1;
1416    uint32_t insn_idx = 0;
1417    for (; insn_idx < insns_size;
1418         insn_idx += Instruction::At(code_item_->insns_ + insn_idx)->SizeInCodeUnits()) {
1419      /*
1420       * Switch-statement data doesn't get "visited" by scanner. It
1421       * may or may not be preceded by a padding NOP (for alignment).
1422       */
1423      if (insns[insn_idx] == Instruction::kPackedSwitchSignature ||
1424          insns[insn_idx] == Instruction::kSparseSwitchSignature ||
1425          insns[insn_idx] == Instruction::kArrayDataSignature ||
1426          (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) &&
1427           (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature ||
1428            insns[insn_idx + 1] == Instruction::kSparseSwitchSignature ||
1429            insns[insn_idx + 1] == Instruction::kArrayDataSignature))) {
1430        insn_flags_[insn_idx].SetVisited();
1431      }
1432
1433      if (!insn_flags_[insn_idx].IsVisited()) {
1434        if (dead_start < 0)
1435          dead_start = insn_idx;
1436      } else if (dead_start >= 0) {
1437        LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
1438                        << "-" << reinterpret_cast<void*>(insn_idx - 1);
1439        dead_start = -1;
1440      }
1441    }
1442    if (dead_start >= 0) {
1443      LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
1444                      << "-" << reinterpret_cast<void*>(insn_idx - 1);
1445    }
1446    // To dump the state of the verify after a method, do something like:
1447    // if (PrettyMethod(dex_method_idx_, *dex_file_) ==
1448    //     "boolean java.lang.String.equals(java.lang.Object)") {
1449    //   LOG(INFO) << info_messages_.str();
1450    // }
1451  }
1452  return true;
1453}
1454
1455bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
1456  // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about.
1457  // We want the state _before_ the instruction, for the case where the dex pc we're
1458  // interested in is itself a monitor-enter instruction (which is a likely place
1459  // for a thread to be suspended).
1460  if (monitor_enter_dex_pcs_ != nullptr && work_insn_idx_ == interesting_dex_pc_) {
1461    monitor_enter_dex_pcs_->clear();  // The new work line is more accurate than the previous one.
1462    for (size_t i = 0; i < work_line_->GetMonitorEnterCount(); ++i) {
1463      monitor_enter_dex_pcs_->push_back(work_line_->GetMonitorEnterDexPc(i));
1464    }
1465  }
1466
1467  /*
1468   * Once we finish decoding the instruction, we need to figure out where
1469   * we can go from here. There are three possible ways to transfer
1470   * control to another statement:
1471   *
1472   * (1) Continue to the next instruction. Applies to all but
1473   *     unconditional branches, method returns, and exception throws.
1474   * (2) Branch to one or more possible locations. Applies to branches
1475   *     and switch statements.
1476   * (3) Exception handlers. Applies to any instruction that can
1477   *     throw an exception that is handled by an encompassing "try"
1478   *     block.
1479   *
1480   * We can also return, in which case there is no successor instruction
1481   * from this point.
1482   *
1483   * The behavior can be determined from the opcode flags.
1484   */
1485  const uint16_t* insns = code_item_->insns_ + work_insn_idx_;
1486  const Instruction* inst = Instruction::At(insns);
1487  int opcode_flags = Instruction::FlagsOf(inst->Opcode());
1488
1489  int32_t branch_target = 0;
1490  bool just_set_result = false;
1491  if (gDebugVerify) {
1492    // Generate processing back trace to debug verifier
1493    LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << "\n"
1494                    << work_line_->Dump(this) << "\n";
1495  }
1496
1497  /*
1498   * Make a copy of the previous register state. If the instruction
1499   * can throw an exception, we will copy/merge this into the "catch"
1500   * address rather than work_line, because we don't want the result
1501   * from the "successful" code path (e.g. a check-cast that "improves"
1502   * a type) to be visible to the exception handler.
1503   */
1504  if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) {
1505    saved_line_->CopyFromLine(work_line_.get());
1506  } else if (kIsDebugBuild) {
1507    saved_line_->FillWithGarbage();
1508  }
1509
1510
1511  // We need to ensure the work line is consistent while performing validation. When we spot a
1512  // peephole pattern we compute a new line for either the fallthrough instruction or the
1513  // branch target.
1514  std::unique_ptr<RegisterLine> branch_line;
1515  std::unique_ptr<RegisterLine> fallthrough_line;
1516
1517  switch (inst->Opcode()) {
1518    case Instruction::NOP:
1519      /*
1520       * A "pure" NOP has no effect on anything. Data tables start with
1521       * a signature that looks like a NOP; if we see one of these in
1522       * the course of executing code then we have a problem.
1523       */
1524      if (inst->VRegA_10x() != 0) {
1525        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream";
1526      }
1527      break;
1528
1529    case Instruction::MOVE:
1530      work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr);
1531      break;
1532    case Instruction::MOVE_FROM16:
1533      work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr);
1534      break;
1535    case Instruction::MOVE_16:
1536      work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr);
1537      break;
1538    case Instruction::MOVE_WIDE:
1539      work_line_->CopyRegister2(this, inst->VRegA_12x(), inst->VRegB_12x());
1540      break;
1541    case Instruction::MOVE_WIDE_FROM16:
1542      work_line_->CopyRegister2(this, inst->VRegA_22x(), inst->VRegB_22x());
1543      break;
1544    case Instruction::MOVE_WIDE_16:
1545      work_line_->CopyRegister2(this, inst->VRegA_32x(), inst->VRegB_32x());
1546      break;
1547    case Instruction::MOVE_OBJECT:
1548      work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef);
1549      break;
1550    case Instruction::MOVE_OBJECT_FROM16:
1551      work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef);
1552      break;
1553    case Instruction::MOVE_OBJECT_16:
1554      work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef);
1555      break;
1556
1557    /*
1558     * The move-result instructions copy data out of a "pseudo-register"
1559     * with the results from the last method invocation. In practice we
1560     * might want to hold the result in an actual CPU register, so the
1561     * Dalvik spec requires that these only appear immediately after an
1562     * invoke or filled-new-array.
1563     *
1564     * These calls invalidate the "result" register. (This is now
1565     * redundant with the reset done below, but it can make the debug info
1566     * easier to read in some cases.)
1567     */
1568    case Instruction::MOVE_RESULT:
1569      work_line_->CopyResultRegister1(this, inst->VRegA_11x(), false);
1570      break;
1571    case Instruction::MOVE_RESULT_WIDE:
1572      work_line_->CopyResultRegister2(this, inst->VRegA_11x());
1573      break;
1574    case Instruction::MOVE_RESULT_OBJECT:
1575      work_line_->CopyResultRegister1(this, inst->VRegA_11x(), true);
1576      break;
1577
1578    case Instruction::MOVE_EXCEPTION: {
1579      /*
1580       * This statement can only appear as the first instruction in an exception handler. We verify
1581       * that as part of extracting the exception type from the catch block list.
1582       */
1583      const RegType& res_type = GetCaughtExceptionType();
1584      work_line_->SetRegisterType(this, inst->VRegA_11x(), res_type);
1585      break;
1586    }
1587    case Instruction::RETURN_VOID:
1588      if (!IsConstructor() || work_line_->CheckConstructorReturn(this)) {
1589        if (!GetMethodReturnType().IsConflict()) {
1590          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
1591        }
1592      }
1593      break;
1594    case Instruction::RETURN:
1595      if (!IsConstructor() || work_line_->CheckConstructorReturn(this)) {
1596        /* check the method signature */
1597        const RegType& return_type = GetMethodReturnType();
1598        if (!return_type.IsCategory1Types()) {
1599          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type "
1600                                            << return_type;
1601        } else {
1602          // Compilers may generate synthetic functions that write byte values into boolean fields.
1603          // Also, it may use integer values for boolean, byte, short, and character return types.
1604          const uint32_t vregA = inst->VRegA_11x();
1605          const RegType& src_type = work_line_->GetRegisterType(this, vregA);
1606          bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) ||
1607                          ((return_type.IsBoolean() || return_type.IsByte() ||
1608                           return_type.IsShort() || return_type.IsChar()) &&
1609                           src_type.IsInteger()));
1610          /* check the register contents */
1611          bool success =
1612              work_line_->VerifyRegisterType(this, vregA, use_src ? src_type : return_type);
1613          if (!success) {
1614            AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA));
1615          }
1616        }
1617      }
1618      break;
1619    case Instruction::RETURN_WIDE:
1620      if (!IsConstructor() || work_line_->CheckConstructorReturn(this)) {
1621        /* check the method signature */
1622        const RegType& return_type = GetMethodReturnType();
1623        if (!return_type.IsCategory2Types()) {
1624          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected";
1625        } else {
1626          /* check the register contents */
1627          const uint32_t vregA = inst->VRegA_11x();
1628          bool success = work_line_->VerifyRegisterType(this, vregA, return_type);
1629          if (!success) {
1630            AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA));
1631          }
1632        }
1633      }
1634      break;
1635    case Instruction::RETURN_OBJECT:
1636      if (!IsConstructor() || work_line_->CheckConstructorReturn(this)) {
1637        const RegType& return_type = GetMethodReturnType();
1638        if (!return_type.IsReferenceTypes()) {
1639          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected";
1640        } else {
1641          /* return_type is the *expected* return type, not register value */
1642          DCHECK(!return_type.IsZero());
1643          DCHECK(!return_type.IsUninitializedReference());
1644          const uint32_t vregA = inst->VRegA_11x();
1645          const RegType& reg_type = work_line_->GetRegisterType(this, vregA);
1646          // Disallow returning uninitialized values and verify that the reference in vAA is an
1647          // instance of the "return_type"
1648          if (reg_type.IsUninitializedTypes()) {
1649            Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "returning uninitialized object '"
1650                                              << reg_type << "'";
1651          } else if (!return_type.IsAssignableFrom(reg_type)) {
1652            if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) {
1653              Fail(VERIFY_ERROR_NO_CLASS) << " can't resolve returned type '" << return_type
1654                  << "' or '" << reg_type << "'";
1655            } else {
1656              Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
1657                  << "', but expected from declaration '" << return_type << "'";
1658            }
1659          }
1660        }
1661      }
1662      break;
1663
1664      /* could be boolean, int, float, or a null reference */
1665    case Instruction::CONST_4: {
1666      int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
1667      work_line_->SetRegisterType(this, inst->VRegA_11n(),
1668                                  DetermineCat1Constant(val, need_precise_constants_));
1669      break;
1670    }
1671    case Instruction::CONST_16: {
1672      int16_t val = static_cast<int16_t>(inst->VRegB_21s());
1673      work_line_->SetRegisterType(this, inst->VRegA_21s(),
1674                                  DetermineCat1Constant(val, need_precise_constants_));
1675      break;
1676    }
1677    case Instruction::CONST: {
1678      int32_t val = inst->VRegB_31i();
1679      work_line_->SetRegisterType(this, inst->VRegA_31i(),
1680                                  DetermineCat1Constant(val, need_precise_constants_));
1681      break;
1682    }
1683    case Instruction::CONST_HIGH16: {
1684      int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
1685      work_line_->SetRegisterType(this, inst->VRegA_21h(),
1686                                  DetermineCat1Constant(val, need_precise_constants_));
1687      break;
1688    }
1689      /* could be long or double; resolved upon use */
1690    case Instruction::CONST_WIDE_16: {
1691      int64_t val = static_cast<int16_t>(inst->VRegB_21s());
1692      const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
1693      const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
1694      work_line_->SetRegisterTypeWide(this, inst->VRegA_21s(), lo, hi);
1695      break;
1696    }
1697    case Instruction::CONST_WIDE_32: {
1698      int64_t val = static_cast<int32_t>(inst->VRegB_31i());
1699      const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
1700      const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
1701      work_line_->SetRegisterTypeWide(this, inst->VRegA_31i(), lo, hi);
1702      break;
1703    }
1704    case Instruction::CONST_WIDE: {
1705      int64_t val = inst->VRegB_51l();
1706      const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
1707      const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
1708      work_line_->SetRegisterTypeWide(this, inst->VRegA_51l(), lo, hi);
1709      break;
1710    }
1711    case Instruction::CONST_WIDE_HIGH16: {
1712      int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48;
1713      const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
1714      const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
1715      work_line_->SetRegisterTypeWide(this, inst->VRegA_21h(), lo, hi);
1716      break;
1717    }
1718    case Instruction::CONST_STRING:
1719      work_line_->SetRegisterType(this, inst->VRegA_21c(), reg_types_.JavaLangString());
1720      break;
1721    case Instruction::CONST_STRING_JUMBO:
1722      work_line_->SetRegisterType(this, inst->VRegA_31c(), reg_types_.JavaLangString());
1723      break;
1724    case Instruction::CONST_CLASS: {
1725      // Get type from instruction if unresolved then we need an access check
1726      // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
1727      const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
1728      // Register holds class, ie its type is class, on error it will hold Conflict.
1729      work_line_->SetRegisterType(this, inst->VRegA_21c(),
1730                                  res_type.IsConflict() ? res_type
1731                                                        : reg_types_.JavaLangClass());
1732      break;
1733    }
1734    case Instruction::MONITOR_ENTER:
1735      work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_);
1736      break;
1737    case Instruction::MONITOR_EXIT:
1738      /*
1739       * monitor-exit instructions are odd. They can throw exceptions,
1740       * but when they do they act as if they succeeded and the PC is
1741       * pointing to the following instruction. (This behavior goes back
1742       * to the need to handle asynchronous exceptions, a now-deprecated
1743       * feature that Dalvik doesn't support.)
1744       *
1745       * In practice we don't need to worry about this. The only
1746       * exceptions that can be thrown from monitor-exit are for a
1747       * null reference and -exit without a matching -enter. If the
1748       * structured locking checks are working, the former would have
1749       * failed on the -enter instruction, and the latter is impossible.
1750       *
1751       * This is fortunate, because issue 3221411 prevents us from
1752       * chasing the "can throw" path when monitor verification is
1753       * enabled. If we can fully verify the locking we can ignore
1754       * some catch blocks (which will show up as "dead" code when
1755       * we skip them here); if we can't, then the code path could be
1756       * "live" so we still need to check it.
1757       */
1758      opcode_flags &= ~Instruction::kThrow;
1759      work_line_->PopMonitor(this, inst->VRegA_11x());
1760      break;
1761
1762    case Instruction::CHECK_CAST:
1763    case Instruction::INSTANCE_OF: {
1764      /*
1765       * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This
1766       * could be a "upcast" -- not expected, so we don't try to address it.)
1767       *
1768       * If it fails, an exception is thrown, which we deal with later by ignoring the update to
1769       * dec_insn.vA when branching to a handler.
1770       */
1771      const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST);
1772      const uint32_t type_idx = (is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c();
1773      const RegType& res_type = ResolveClassAndCheckAccess(type_idx);
1774      if (res_type.IsConflict()) {
1775        // If this is a primitive type, fail HARD.
1776        mirror::Class* klass = dex_cache_->GetResolvedType(type_idx);
1777        if (klass != nullptr && klass->IsPrimitive()) {
1778          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type "
1779              << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in "
1780              << GetDeclaringClass();
1781          break;
1782        }
1783
1784        DCHECK_NE(failures_.size(), 0U);
1785        if (!is_checkcast) {
1786          work_line_->SetRegisterType(this, inst->VRegA_22c(), reg_types_.Boolean());
1787        }
1788        break;  // bad class
1789      }
1790      // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
1791      uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c();
1792      const RegType& orig_type = work_line_->GetRegisterType(this, orig_type_reg);
1793      if (!res_type.IsNonZeroReferenceTypes()) {
1794        if (is_checkcast) {
1795          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type;
1796        } else {
1797          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type;
1798        }
1799      } else if (!orig_type.IsReferenceTypes()) {
1800        if (is_checkcast) {
1801          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg;
1802        } else {
1803          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg;
1804        }
1805      } else {
1806        if (is_checkcast) {
1807          work_line_->SetRegisterType(this, inst->VRegA_21c(), res_type);
1808        } else {
1809          work_line_->SetRegisterType(this, inst->VRegA_22c(), reg_types_.Boolean());
1810        }
1811      }
1812      break;
1813    }
1814    case Instruction::ARRAY_LENGTH: {
1815      const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegB_12x());
1816      if (res_type.IsReferenceTypes()) {
1817        if (!res_type.IsArrayTypes() && !res_type.IsZero()) {  // ie not an array or null
1818          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
1819        } else {
1820          work_line_->SetRegisterType(this, inst->VRegA_12x(), reg_types_.Integer());
1821        }
1822      } else {
1823        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
1824      }
1825      break;
1826    }
1827    case Instruction::NEW_INSTANCE: {
1828      const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
1829      if (res_type.IsConflict()) {
1830        DCHECK_NE(failures_.size(), 0U);
1831        break;  // bad class
1832      }
1833      // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
1834      // can't create an instance of an interface or abstract class */
1835      if (!res_type.IsInstantiableTypes()) {
1836        Fail(VERIFY_ERROR_INSTANTIATION)
1837            << "new-instance on primitive, interface or abstract class" << res_type;
1838        // Soft failure so carry on to set register type.
1839      }
1840      const RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_);
1841      // Any registers holding previous allocations from this address that have not yet been
1842      // initialized must be marked invalid.
1843      work_line_->MarkUninitRefsAsInvalid(this, uninit_type);
1844      // add the new uninitialized reference to the register state
1845      work_line_->SetRegisterType(this, inst->VRegA_21c(), uninit_type);
1846      break;
1847    }
1848    case Instruction::NEW_ARRAY:
1849      VerifyNewArray(inst, false, false);
1850      break;
1851    case Instruction::FILLED_NEW_ARRAY:
1852      VerifyNewArray(inst, true, false);
1853      just_set_result = true;  // Filled new array sets result register
1854      break;
1855    case Instruction::FILLED_NEW_ARRAY_RANGE:
1856      VerifyNewArray(inst, true, true);
1857      just_set_result = true;  // Filled new array range sets result register
1858      break;
1859    case Instruction::CMPL_FLOAT:
1860    case Instruction::CMPG_FLOAT:
1861      if (!work_line_->VerifyRegisterType(this, inst->VRegB_23x(), reg_types_.Float())) {
1862        break;
1863      }
1864      if (!work_line_->VerifyRegisterType(this, inst->VRegC_23x(), reg_types_.Float())) {
1865        break;
1866      }
1867      work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Integer());
1868      break;
1869    case Instruction::CMPL_DOUBLE:
1870    case Instruction::CMPG_DOUBLE:
1871      if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.DoubleLo(),
1872                                              reg_types_.DoubleHi())) {
1873        break;
1874      }
1875      if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.DoubleLo(),
1876                                              reg_types_.DoubleHi())) {
1877        break;
1878      }
1879      work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Integer());
1880      break;
1881    case Instruction::CMP_LONG:
1882      if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.LongLo(),
1883                                              reg_types_.LongHi())) {
1884        break;
1885      }
1886      if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.LongLo(),
1887                                              reg_types_.LongHi())) {
1888        break;
1889      }
1890      work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Integer());
1891      break;
1892    case Instruction::THROW: {
1893      const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x());
1894      if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type)) {
1895        Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT)
1896            << "thrown class " << res_type << " not instanceof Throwable";
1897      }
1898      break;
1899    }
1900    case Instruction::GOTO:
1901    case Instruction::GOTO_16:
1902    case Instruction::GOTO_32:
1903      /* no effect on or use of registers */
1904      break;
1905
1906    case Instruction::PACKED_SWITCH:
1907    case Instruction::SPARSE_SWITCH:
1908      /* verify that vAA is an integer, or can be converted to one */
1909      work_line_->VerifyRegisterType(this, inst->VRegA_31t(), reg_types_.Integer());
1910      break;
1911
1912    case Instruction::FILL_ARRAY_DATA: {
1913      /* Similar to the verification done for APUT */
1914      const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegA_31t());
1915      /* array_type can be null if the reg type is Zero */
1916      if (!array_type.IsZero()) {
1917        if (!array_type.IsArrayTypes()) {
1918          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type "
1919                                            << array_type;
1920        } else {
1921          const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
1922          DCHECK(!component_type.IsConflict());
1923          if (component_type.IsNonZeroReferenceTypes()) {
1924            Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type "
1925                                              << component_type;
1926          } else {
1927            // Now verify if the element width in the table matches the element width declared in
1928            // the array
1929            const uint16_t* array_data = insns + (insns[1] | (((int32_t) insns[2]) << 16));
1930            if (array_data[0] != Instruction::kArrayDataSignature) {
1931              Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data";
1932            } else {
1933              size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
1934              // Since we don't compress the data in Dex, expect to see equal width of data stored
1935              // in the table and expected from the array class.
1936              if (array_data[1] != elem_width) {
1937                Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1]
1938                                                  << " vs " << elem_width << ")";
1939              }
1940            }
1941          }
1942        }
1943      }
1944      break;
1945    }
1946    case Instruction::IF_EQ:
1947    case Instruction::IF_NE: {
1948      const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
1949      const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
1950      bool mismatch = false;
1951      if (reg_type1.IsZero()) {  // zero then integral or reference expected
1952        mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes();
1953      } else if (reg_type1.IsReferenceTypes()) {  // both references?
1954        mismatch = !reg_type2.IsReferenceTypes();
1955      } else {  // both integral?
1956        mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes();
1957      }
1958      if (mismatch) {
1959        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << ","
1960                                          << reg_type2 << ") must both be references or integral";
1961      }
1962      break;
1963    }
1964    case Instruction::IF_LT:
1965    case Instruction::IF_GE:
1966    case Instruction::IF_GT:
1967    case Instruction::IF_LE: {
1968      const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
1969      const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
1970      if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) {
1971        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << ","
1972                                          << reg_type2 << ") must be integral";
1973      }
1974      break;
1975    }
1976    case Instruction::IF_EQZ:
1977    case Instruction::IF_NEZ: {
1978      const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
1979      if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) {
1980        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
1981                                          << " unexpected as arg to if-eqz/if-nez";
1982      }
1983
1984      // Find previous instruction - its existence is a precondition to peephole optimization.
1985      uint32_t instance_of_idx = 0;
1986      if (0 != work_insn_idx_) {
1987        instance_of_idx = work_insn_idx_ - 1;
1988        while (0 != instance_of_idx && !insn_flags_[instance_of_idx].IsOpcode()) {
1989          instance_of_idx--;
1990        }
1991        CHECK(insn_flags_[instance_of_idx].IsOpcode());
1992      } else {
1993        break;
1994      }
1995
1996      const Instruction* instance_of_inst = Instruction::At(code_item_->insns_ + instance_of_idx);
1997
1998      /* Check for peep-hole pattern of:
1999       *    ...;
2000       *    instance-of vX, vY, T;
2001       *    ifXXX vX, label ;
2002       *    ...;
2003       * label:
2004       *    ...;
2005       * and sharpen the type of vY to be type T.
2006       * Note, this pattern can't be if:
2007       *  - if there are other branches to this branch,
2008       *  - when vX == vY.
2009       */
2010      if (!CurrentInsnFlags()->IsBranchTarget() &&
2011          (Instruction::INSTANCE_OF == instance_of_inst->Opcode()) &&
2012          (inst->VRegA_21t() == instance_of_inst->VRegA_22c()) &&
2013          (instance_of_inst->VRegA_22c() != instance_of_inst->VRegB_22c())) {
2014        // Check the type of the instance-of is different than that of registers type, as if they
2015        // are the same there is no work to be done here. Check that the conversion is not to or
2016        // from an unresolved type as type information is imprecise. If the instance-of is to an
2017        // interface then ignore the type information as interfaces can only be treated as Objects
2018        // and we don't want to disallow field and other operations on the object. If the value
2019        // being instance-of checked against is known null (zero) then allow the optimization as
2020        // we didn't have type information. If the merge of the instance-of type with the original
2021        // type is assignable to the original then allow optimization. This check is performed to
2022        // ensure that subsequent merges don't lose type information - such as becoming an
2023        // interface from a class that would lose information relevant to field checks.
2024        const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst->VRegB_22c());
2025        const RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c());
2026
2027        if (!orig_type.Equals(cast_type) &&
2028            !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() &&
2029            cast_type.HasClass() &&             // Could be conflict type, make sure it has a class.
2030            !cast_type.GetClass()->IsInterface() &&
2031            (orig_type.IsZero() ||
2032                orig_type.IsStrictlyAssignableFrom(cast_type.Merge(orig_type, &reg_types_)))) {
2033          RegisterLine* update_line = RegisterLine::Create(code_item_->registers_size_, this);
2034          if (inst->Opcode() == Instruction::IF_EQZ) {
2035            fallthrough_line.reset(update_line);
2036          } else {
2037            branch_line.reset(update_line);
2038          }
2039          update_line->CopyFromLine(work_line_.get());
2040          update_line->SetRegisterType(this, instance_of_inst->VRegB_22c(), cast_type);
2041          if (!insn_flags_[instance_of_idx].IsBranchTarget() && 0 != instance_of_idx) {
2042            // See if instance-of was preceded by a move-object operation, common due to the small
2043            // register encoding space of instance-of, and propagate type information to the source
2044            // of the move-object.
2045            uint32_t move_idx = instance_of_idx - 1;
2046            while (0 != move_idx && !insn_flags_[move_idx].IsOpcode()) {
2047              move_idx--;
2048            }
2049            CHECK(insn_flags_[move_idx].IsOpcode());
2050            const Instruction* move_inst = Instruction::At(code_item_->insns_ + move_idx);
2051            switch (move_inst->Opcode()) {
2052              case Instruction::MOVE_OBJECT:
2053                if (move_inst->VRegA_12x() == instance_of_inst->VRegB_22c()) {
2054                  update_line->SetRegisterType(this, move_inst->VRegB_12x(), cast_type);
2055                }
2056                break;
2057              case Instruction::MOVE_OBJECT_FROM16:
2058                if (move_inst->VRegA_22x() == instance_of_inst->VRegB_22c()) {
2059                  update_line->SetRegisterType(this, move_inst->VRegB_22x(), cast_type);
2060                }
2061                break;
2062              case Instruction::MOVE_OBJECT_16:
2063                if (move_inst->VRegA_32x() == instance_of_inst->VRegB_22c()) {
2064                  update_line->SetRegisterType(this, move_inst->VRegB_32x(), cast_type);
2065                }
2066                break;
2067              default:
2068                break;
2069            }
2070          }
2071        }
2072      }
2073
2074      break;
2075    }
2076    case Instruction::IF_LTZ:
2077    case Instruction::IF_GEZ:
2078    case Instruction::IF_GTZ:
2079    case Instruction::IF_LEZ: {
2080      const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
2081      if (!reg_type.IsIntegralTypes()) {
2082        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
2083                                          << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez";
2084      }
2085      break;
2086    }
2087    case Instruction::AGET_BOOLEAN:
2088      VerifyAGet(inst, reg_types_.Boolean(), true);
2089      break;
2090    case Instruction::AGET_BYTE:
2091      VerifyAGet(inst, reg_types_.Byte(), true);
2092      break;
2093    case Instruction::AGET_CHAR:
2094      VerifyAGet(inst, reg_types_.Char(), true);
2095      break;
2096    case Instruction::AGET_SHORT:
2097      VerifyAGet(inst, reg_types_.Short(), true);
2098      break;
2099    case Instruction::AGET:
2100      VerifyAGet(inst, reg_types_.Integer(), true);
2101      break;
2102    case Instruction::AGET_WIDE:
2103      VerifyAGet(inst, reg_types_.LongLo(), true);
2104      break;
2105    case Instruction::AGET_OBJECT:
2106      VerifyAGet(inst, reg_types_.JavaLangObject(false), false);
2107      break;
2108
2109    case Instruction::APUT_BOOLEAN:
2110      VerifyAPut(inst, reg_types_.Boolean(), true);
2111      break;
2112    case Instruction::APUT_BYTE:
2113      VerifyAPut(inst, reg_types_.Byte(), true);
2114      break;
2115    case Instruction::APUT_CHAR:
2116      VerifyAPut(inst, reg_types_.Char(), true);
2117      break;
2118    case Instruction::APUT_SHORT:
2119      VerifyAPut(inst, reg_types_.Short(), true);
2120      break;
2121    case Instruction::APUT:
2122      VerifyAPut(inst, reg_types_.Integer(), true);
2123      break;
2124    case Instruction::APUT_WIDE:
2125      VerifyAPut(inst, reg_types_.LongLo(), true);
2126      break;
2127    case Instruction::APUT_OBJECT:
2128      VerifyAPut(inst, reg_types_.JavaLangObject(false), false);
2129      break;
2130
2131    case Instruction::IGET_BOOLEAN:
2132      VerifyISGet(inst, reg_types_.Boolean(), true, false);
2133      break;
2134    case Instruction::IGET_BYTE:
2135      VerifyISGet(inst, reg_types_.Byte(), true, false);
2136      break;
2137    case Instruction::IGET_CHAR:
2138      VerifyISGet(inst, reg_types_.Char(), true, false);
2139      break;
2140    case Instruction::IGET_SHORT:
2141      VerifyISGet(inst, reg_types_.Short(), true, false);
2142      break;
2143    case Instruction::IGET:
2144      VerifyISGet(inst, reg_types_.Integer(), true, false);
2145      break;
2146    case Instruction::IGET_WIDE:
2147      VerifyISGet(inst, reg_types_.LongLo(), true, false);
2148      break;
2149    case Instruction::IGET_OBJECT:
2150      VerifyISGet(inst, reg_types_.JavaLangObject(false), false, false);
2151      break;
2152
2153    case Instruction::IPUT_BOOLEAN:
2154      VerifyISPut(inst, reg_types_.Boolean(), true, false);
2155      break;
2156    case Instruction::IPUT_BYTE:
2157      VerifyISPut(inst, reg_types_.Byte(), true, false);
2158      break;
2159    case Instruction::IPUT_CHAR:
2160      VerifyISPut(inst, reg_types_.Char(), true, false);
2161      break;
2162    case Instruction::IPUT_SHORT:
2163      VerifyISPut(inst, reg_types_.Short(), true, false);
2164      break;
2165    case Instruction::IPUT:
2166      VerifyISPut(inst, reg_types_.Integer(), true, false);
2167      break;
2168    case Instruction::IPUT_WIDE:
2169      VerifyISPut(inst, reg_types_.LongLo(), true, false);
2170      break;
2171    case Instruction::IPUT_OBJECT:
2172      VerifyISPut(inst, reg_types_.JavaLangObject(false), false, false);
2173      break;
2174
2175    case Instruction::SGET_BOOLEAN:
2176      VerifyISGet(inst, reg_types_.Boolean(), true, true);
2177      break;
2178    case Instruction::SGET_BYTE:
2179      VerifyISGet(inst, reg_types_.Byte(), true, true);
2180      break;
2181    case Instruction::SGET_CHAR:
2182      VerifyISGet(inst, reg_types_.Char(), true, true);
2183      break;
2184    case Instruction::SGET_SHORT:
2185      VerifyISGet(inst, reg_types_.Short(), true, true);
2186      break;
2187    case Instruction::SGET:
2188      VerifyISGet(inst, reg_types_.Integer(), true, true);
2189      break;
2190    case Instruction::SGET_WIDE:
2191      VerifyISGet(inst, reg_types_.LongLo(), true, true);
2192      break;
2193    case Instruction::SGET_OBJECT:
2194      VerifyISGet(inst, reg_types_.JavaLangObject(false), false, true);
2195      break;
2196
2197    case Instruction::SPUT_BOOLEAN:
2198      VerifyISPut(inst, reg_types_.Boolean(), true, true);
2199      break;
2200    case Instruction::SPUT_BYTE:
2201      VerifyISPut(inst, reg_types_.Byte(), true, true);
2202      break;
2203    case Instruction::SPUT_CHAR:
2204      VerifyISPut(inst, reg_types_.Char(), true, true);
2205      break;
2206    case Instruction::SPUT_SHORT:
2207      VerifyISPut(inst, reg_types_.Short(), true, true);
2208      break;
2209    case Instruction::SPUT:
2210      VerifyISPut(inst, reg_types_.Integer(), true, true);
2211      break;
2212    case Instruction::SPUT_WIDE:
2213      VerifyISPut(inst, reg_types_.LongLo(), true, true);
2214      break;
2215    case Instruction::SPUT_OBJECT:
2216      VerifyISPut(inst, reg_types_.JavaLangObject(false), false, true);
2217      break;
2218
2219    case Instruction::INVOKE_VIRTUAL:
2220    case Instruction::INVOKE_VIRTUAL_RANGE:
2221    case Instruction::INVOKE_SUPER:
2222    case Instruction::INVOKE_SUPER_RANGE: {
2223      bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE ||
2224                       inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
2225      bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
2226                       inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
2227      mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_VIRTUAL, is_range,
2228                                                              is_super);
2229      const RegType* return_type = nullptr;
2230      if (called_method != nullptr) {
2231        StackHandleScope<1> hs(self_);
2232        Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
2233        MethodHelper mh(h_called_method);
2234        mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
2235        if (return_type_class != nullptr) {
2236          return_type = &reg_types_.FromClass(h_called_method->GetReturnTypeDescriptor(),
2237                                              return_type_class,
2238                                              return_type_class->CannotBeAssignedFromOtherTypes());
2239        } else {
2240          DCHECK(!can_load_classes_ || self_->IsExceptionPending());
2241          self_->ClearException();
2242        }
2243      }
2244      if (return_type == nullptr) {
2245        uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
2246        const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
2247        uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
2248        const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx);
2249        return_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
2250      }
2251      if (!return_type->IsLowHalf()) {
2252        work_line_->SetResultRegisterType(this, *return_type);
2253      } else {
2254        work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
2255      }
2256      just_set_result = true;
2257      break;
2258    }
2259    case Instruction::INVOKE_DIRECT:
2260    case Instruction::INVOKE_DIRECT_RANGE: {
2261      bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
2262      mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT,
2263                                                                   is_range, false);
2264      const char* return_type_descriptor;
2265      bool is_constructor;
2266      const RegType* return_type = nullptr;
2267      if (called_method == nullptr) {
2268        uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
2269        const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
2270        is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0;
2271        uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
2272        return_type_descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
2273      } else {
2274        is_constructor = called_method->IsConstructor();
2275        return_type_descriptor = called_method->GetReturnTypeDescriptor();
2276        StackHandleScope<1> hs(self_);
2277        Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
2278        MethodHelper mh(h_called_method);
2279        mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
2280        if (return_type_class != nullptr) {
2281          return_type = &reg_types_.FromClass(return_type_descriptor,
2282                                              return_type_class,
2283                                              return_type_class->CannotBeAssignedFromOtherTypes());
2284        } else {
2285          DCHECK(!can_load_classes_ || self_->IsExceptionPending());
2286          self_->ClearException();
2287        }
2288      }
2289      if (is_constructor) {
2290        /*
2291         * Some additional checks when calling a constructor. We know from the invocation arg check
2292         * that the "this" argument is an instance of called_method->klass. Now we further restrict
2293         * that to require that called_method->klass is the same as this->klass or this->super,
2294         * allowing the latter only if the "this" argument is the same as the "this" argument to
2295         * this method (which implies that we're in a constructor ourselves).
2296         */
2297        const RegType& this_type = work_line_->GetInvocationThis(this, inst, is_range);
2298        if (this_type.IsConflict())  // failure.
2299          break;
2300
2301        /* no null refs allowed (?) */
2302        if (this_type.IsZero()) {
2303          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref";
2304          break;
2305        }
2306
2307        /* must be in same class or in superclass */
2308        // const RegType& this_super_klass = this_type.GetSuperClass(&reg_types_);
2309        // TODO: re-enable constructor type verification
2310        // if (this_super_klass.IsConflict()) {
2311          // Unknown super class, fail so we re-check at runtime.
2312          // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'";
2313          // break;
2314        // }
2315
2316        /* arg must be an uninitialized reference */
2317        if (!this_type.IsUninitializedTypes()) {
2318          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference "
2319              << this_type;
2320          break;
2321        }
2322
2323        /*
2324         * Replace the uninitialized reference with an initialized one. We need to do this for all
2325         * registers that have the same object instance in them, not just the "this" register.
2326         */
2327        work_line_->MarkRefsAsInitialized(this, this_type);
2328      }
2329      if (return_type == nullptr) {
2330        return_type = &reg_types_.FromDescriptor(GetClassLoader(), return_type_descriptor,
2331                                                 false);
2332      }
2333      if (!return_type->IsLowHalf()) {
2334        work_line_->SetResultRegisterType(this, *return_type);
2335      } else {
2336        work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
2337      }
2338      just_set_result = true;
2339      break;
2340    }
2341    case Instruction::INVOKE_STATIC:
2342    case Instruction::INVOKE_STATIC_RANGE: {
2343        bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
2344        mirror::ArtMethod* called_method = VerifyInvocationArgs(inst,
2345                                                                     METHOD_STATIC,
2346                                                                     is_range,
2347                                                                     false);
2348        const char* descriptor;
2349        if (called_method == nullptr) {
2350          uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
2351          const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
2352          uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
2353          descriptor = dex_file_->StringByTypeIdx(return_type_idx);
2354        } else {
2355          descriptor = called_method->GetReturnTypeDescriptor();
2356        }
2357        const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
2358        if (!return_type.IsLowHalf()) {
2359          work_line_->SetResultRegisterType(this, return_type);
2360        } else {
2361          work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
2362        }
2363        just_set_result = true;
2364      }
2365      break;
2366    case Instruction::INVOKE_INTERFACE:
2367    case Instruction::INVOKE_INTERFACE_RANGE: {
2368      bool is_range =  (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE);
2369      mirror::ArtMethod* abs_method = VerifyInvocationArgs(inst,
2370                                                                METHOD_INTERFACE,
2371                                                                is_range,
2372                                                                false);
2373      if (abs_method != nullptr) {
2374        mirror::Class* called_interface = abs_method->GetDeclaringClass();
2375        if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) {
2376          Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '"
2377              << PrettyMethod(abs_method) << "'";
2378          break;
2379        }
2380      }
2381      /* Get the type of the "this" arg, which should either be a sub-interface of called
2382       * interface or Object (see comments in RegType::JoinClass).
2383       */
2384      const RegType& this_type = work_line_->GetInvocationThis(this, inst, is_range);
2385      if (this_type.IsZero()) {
2386        /* null pointer always passes (and always fails at runtime) */
2387      } else {
2388        if (this_type.IsUninitializedTypes()) {
2389          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object "
2390              << this_type;
2391          break;
2392        }
2393        // In the past we have tried to assert that "called_interface" is assignable
2394        // from "this_type.GetClass()", however, as we do an imprecise Join
2395        // (RegType::JoinClass) we don't have full information on what interfaces are
2396        // implemented by "this_type". For example, two classes may implement the same
2397        // interfaces and have a common parent that doesn't implement the interface. The
2398        // join will set "this_type" to the parent class and a test that this implements
2399        // the interface will incorrectly fail.
2400      }
2401      /*
2402       * We don't have an object instance, so we can't find the concrete method. However, all of
2403       * the type information is in the abstract method, so we're good.
2404       */
2405      const char* descriptor;
2406      if (abs_method == nullptr) {
2407        uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
2408        const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
2409        uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
2410        descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
2411      } else {
2412        descriptor = abs_method->GetReturnTypeDescriptor();
2413      }
2414      const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
2415      if (!return_type.IsLowHalf()) {
2416        work_line_->SetResultRegisterType(this, return_type);
2417      } else {
2418        work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
2419      }
2420      just_set_result = true;
2421      break;
2422    }
2423    case Instruction::NEG_INT:
2424    case Instruction::NOT_INT:
2425      work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer());
2426      break;
2427    case Instruction::NEG_LONG:
2428    case Instruction::NOT_LONG:
2429      work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2430                                   reg_types_.LongLo(), reg_types_.LongHi());
2431      break;
2432    case Instruction::NEG_FLOAT:
2433      work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Float());
2434      break;
2435    case Instruction::NEG_DOUBLE:
2436      work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2437                                   reg_types_.DoubleLo(), reg_types_.DoubleHi());
2438      break;
2439    case Instruction::INT_TO_LONG:
2440      work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2441                                     reg_types_.Integer());
2442      break;
2443    case Instruction::INT_TO_FLOAT:
2444      work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Integer());
2445      break;
2446    case Instruction::INT_TO_DOUBLE:
2447      work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2448                                     reg_types_.Integer());
2449      break;
2450    case Instruction::LONG_TO_INT:
2451      work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(),
2452                                       reg_types_.LongLo(), reg_types_.LongHi());
2453      break;
2454    case Instruction::LONG_TO_FLOAT:
2455      work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(),
2456                                       reg_types_.LongLo(), reg_types_.LongHi());
2457      break;
2458    case Instruction::LONG_TO_DOUBLE:
2459      work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2460                                   reg_types_.LongLo(), reg_types_.LongHi());
2461      break;
2462    case Instruction::FLOAT_TO_INT:
2463      work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Float());
2464      break;
2465    case Instruction::FLOAT_TO_LONG:
2466      work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2467                                     reg_types_.Float());
2468      break;
2469    case Instruction::FLOAT_TO_DOUBLE:
2470      work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2471                                     reg_types_.Float());
2472      break;
2473    case Instruction::DOUBLE_TO_INT:
2474      work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(),
2475                                       reg_types_.DoubleLo(), reg_types_.DoubleHi());
2476      break;
2477    case Instruction::DOUBLE_TO_LONG:
2478      work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2479                                   reg_types_.DoubleLo(), reg_types_.DoubleHi());
2480      break;
2481    case Instruction::DOUBLE_TO_FLOAT:
2482      work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(),
2483                                       reg_types_.DoubleLo(), reg_types_.DoubleHi());
2484      break;
2485    case Instruction::INT_TO_BYTE:
2486      work_line_->CheckUnaryOp(this, inst, reg_types_.Byte(), reg_types_.Integer());
2487      break;
2488    case Instruction::INT_TO_CHAR:
2489      work_line_->CheckUnaryOp(this, inst, reg_types_.Char(), reg_types_.Integer());
2490      break;
2491    case Instruction::INT_TO_SHORT:
2492      work_line_->CheckUnaryOp(this, inst, reg_types_.Short(), reg_types_.Integer());
2493      break;
2494
2495    case Instruction::ADD_INT:
2496    case Instruction::SUB_INT:
2497    case Instruction::MUL_INT:
2498    case Instruction::REM_INT:
2499    case Instruction::DIV_INT:
2500    case Instruction::SHL_INT:
2501    case Instruction::SHR_INT:
2502    case Instruction::USHR_INT:
2503      work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(),
2504                                reg_types_.Integer(), false);
2505      break;
2506    case Instruction::AND_INT:
2507    case Instruction::OR_INT:
2508    case Instruction::XOR_INT:
2509      work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(),
2510                                reg_types_.Integer(), true);
2511      break;
2512    case Instruction::ADD_LONG:
2513    case Instruction::SUB_LONG:
2514    case Instruction::MUL_LONG:
2515    case Instruction::DIV_LONG:
2516    case Instruction::REM_LONG:
2517    case Instruction::AND_LONG:
2518    case Instruction::OR_LONG:
2519    case Instruction::XOR_LONG:
2520      work_line_->CheckBinaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2521                                    reg_types_.LongLo(), reg_types_.LongHi(),
2522                                    reg_types_.LongLo(), reg_types_.LongHi());
2523      break;
2524    case Instruction::SHL_LONG:
2525    case Instruction::SHR_LONG:
2526    case Instruction::USHR_LONG:
2527      /* shift distance is Int, making these different from other binary operations */
2528      work_line_->CheckBinaryOpWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2529                                         reg_types_.Integer());
2530      break;
2531    case Instruction::ADD_FLOAT:
2532    case Instruction::SUB_FLOAT:
2533    case Instruction::MUL_FLOAT:
2534    case Instruction::DIV_FLOAT:
2535    case Instruction::REM_FLOAT:
2536      work_line_->CheckBinaryOp(this, inst, reg_types_.Float(), reg_types_.Float(),
2537                                reg_types_.Float(), false);
2538      break;
2539    case Instruction::ADD_DOUBLE:
2540    case Instruction::SUB_DOUBLE:
2541    case Instruction::MUL_DOUBLE:
2542    case Instruction::DIV_DOUBLE:
2543    case Instruction::REM_DOUBLE:
2544      work_line_->CheckBinaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2545                                    reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2546                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
2547      break;
2548    case Instruction::ADD_INT_2ADDR:
2549    case Instruction::SUB_INT_2ADDR:
2550    case Instruction::MUL_INT_2ADDR:
2551    case Instruction::REM_INT_2ADDR:
2552    case Instruction::SHL_INT_2ADDR:
2553    case Instruction::SHR_INT_2ADDR:
2554    case Instruction::USHR_INT_2ADDR:
2555      work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
2556                                     reg_types_.Integer(), false);
2557      break;
2558    case Instruction::AND_INT_2ADDR:
2559    case Instruction::OR_INT_2ADDR:
2560    case Instruction::XOR_INT_2ADDR:
2561      work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
2562                                     reg_types_.Integer(), true);
2563      break;
2564    case Instruction::DIV_INT_2ADDR:
2565      work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
2566                                     reg_types_.Integer(), false);
2567      break;
2568    case Instruction::ADD_LONG_2ADDR:
2569    case Instruction::SUB_LONG_2ADDR:
2570    case Instruction::MUL_LONG_2ADDR:
2571    case Instruction::DIV_LONG_2ADDR:
2572    case Instruction::REM_LONG_2ADDR:
2573    case Instruction::AND_LONG_2ADDR:
2574    case Instruction::OR_LONG_2ADDR:
2575    case Instruction::XOR_LONG_2ADDR:
2576      work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2577                                         reg_types_.LongLo(), reg_types_.LongHi(),
2578                                         reg_types_.LongLo(), reg_types_.LongHi());
2579      break;
2580    case Instruction::SHL_LONG_2ADDR:
2581    case Instruction::SHR_LONG_2ADDR:
2582    case Instruction::USHR_LONG_2ADDR:
2583      work_line_->CheckBinaryOp2addrWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
2584                                              reg_types_.Integer());
2585      break;
2586    case Instruction::ADD_FLOAT_2ADDR:
2587    case Instruction::SUB_FLOAT_2ADDR:
2588    case Instruction::MUL_FLOAT_2ADDR:
2589    case Instruction::DIV_FLOAT_2ADDR:
2590    case Instruction::REM_FLOAT_2ADDR:
2591      work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Float(), reg_types_.Float(),
2592                                     reg_types_.Float(), false);
2593      break;
2594    case Instruction::ADD_DOUBLE_2ADDR:
2595    case Instruction::SUB_DOUBLE_2ADDR:
2596    case Instruction::MUL_DOUBLE_2ADDR:
2597    case Instruction::DIV_DOUBLE_2ADDR:
2598    case Instruction::REM_DOUBLE_2ADDR:
2599      work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
2600                                         reg_types_.DoubleLo(),  reg_types_.DoubleHi(),
2601                                         reg_types_.DoubleLo(), reg_types_.DoubleHi());
2602      break;
2603    case Instruction::ADD_INT_LIT16:
2604    case Instruction::RSUB_INT:
2605    case Instruction::MUL_INT_LIT16:
2606    case Instruction::DIV_INT_LIT16:
2607    case Instruction::REM_INT_LIT16:
2608      work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false,
2609                                 true);
2610      break;
2611    case Instruction::AND_INT_LIT16:
2612    case Instruction::OR_INT_LIT16:
2613    case Instruction::XOR_INT_LIT16:
2614      work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true,
2615                                 true);
2616      break;
2617    case Instruction::ADD_INT_LIT8:
2618    case Instruction::RSUB_INT_LIT8:
2619    case Instruction::MUL_INT_LIT8:
2620    case Instruction::DIV_INT_LIT8:
2621    case Instruction::REM_INT_LIT8:
2622    case Instruction::SHL_INT_LIT8:
2623    case Instruction::SHR_INT_LIT8:
2624    case Instruction::USHR_INT_LIT8:
2625      work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false,
2626                                 false);
2627      break;
2628    case Instruction::AND_INT_LIT8:
2629    case Instruction::OR_INT_LIT8:
2630    case Instruction::XOR_INT_LIT8:
2631      work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true,
2632                                 false);
2633      break;
2634
2635    // Special instructions.
2636    case Instruction::RETURN_VOID_BARRIER:
2637      if (!IsConstructor() || IsStatic()) {
2638          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-barrier not expected";
2639      }
2640      break;
2641    // Note: the following instructions encode offsets derived from class linking.
2642    // As such they use Class*/Field*/AbstractMethod* as these offsets only have
2643    // meaning if the class linking and resolution were successful.
2644    case Instruction::IGET_QUICK:
2645      VerifyIGetQuick(inst, reg_types_.Integer(), true);
2646      break;
2647    case Instruction::IGET_WIDE_QUICK:
2648      VerifyIGetQuick(inst, reg_types_.LongLo(), true);
2649      break;
2650    case Instruction::IGET_OBJECT_QUICK:
2651      VerifyIGetQuick(inst, reg_types_.JavaLangObject(false), false);
2652      break;
2653    case Instruction::IPUT_QUICK:
2654      VerifyIPutQuick(inst, reg_types_.Integer(), true);
2655      break;
2656    case Instruction::IPUT_BOOLEAN_QUICK:
2657        VerifyIPutQuick(inst, reg_types_.Boolean(), true);
2658      break;
2659    case Instruction::IPUT_BYTE_QUICK:
2660        VerifyIPutQuick(inst, reg_types_.Byte(), true);
2661      break;
2662    case Instruction::IPUT_CHAR_QUICK:
2663        VerifyIPutQuick(inst, reg_types_.Char(), true);
2664      break;
2665    case Instruction::IPUT_SHORT_QUICK:
2666        VerifyIPutQuick(inst, reg_types_.Short(), true);
2667      break;
2668    case Instruction::IPUT_WIDE_QUICK:
2669      VerifyIPutQuick(inst, reg_types_.LongLo(), true);
2670      break;
2671    case Instruction::IPUT_OBJECT_QUICK:
2672      VerifyIPutQuick(inst, reg_types_.JavaLangObject(false), false);
2673      break;
2674    case Instruction::INVOKE_VIRTUAL_QUICK:
2675    case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
2676      bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
2677      mirror::ArtMethod* called_method = VerifyInvokeVirtualQuickArgs(inst, is_range);
2678      if (called_method != nullptr) {
2679        const char* descriptor = called_method->GetReturnTypeDescriptor();
2680        const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
2681        if (!return_type.IsLowHalf()) {
2682          work_line_->SetResultRegisterType(this, return_type);
2683        } else {
2684          work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
2685        }
2686        just_set_result = true;
2687      }
2688      break;
2689    }
2690
2691    /* These should never appear during verification. */
2692    case Instruction::UNUSED_3E:
2693    case Instruction::UNUSED_3F:
2694    case Instruction::UNUSED_40:
2695    case Instruction::UNUSED_41:
2696    case Instruction::UNUSED_42:
2697    case Instruction::UNUSED_43:
2698    case Instruction::UNUSED_79:
2699    case Instruction::UNUSED_7A:
2700    case Instruction::UNUSED_EF:
2701    case Instruction::UNUSED_F0:
2702    case Instruction::UNUSED_F1:
2703    case Instruction::UNUSED_F2:
2704    case Instruction::UNUSED_F3:
2705    case Instruction::UNUSED_F4:
2706    case Instruction::UNUSED_F5:
2707    case Instruction::UNUSED_F6:
2708    case Instruction::UNUSED_F7:
2709    case Instruction::UNUSED_F8:
2710    case Instruction::UNUSED_F9:
2711    case Instruction::UNUSED_FA:
2712    case Instruction::UNUSED_FB:
2713    case Instruction::UNUSED_FC:
2714    case Instruction::UNUSED_FD:
2715    case Instruction::UNUSED_FE:
2716    case Instruction::UNUSED_FF:
2717      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_);
2718      break;
2719
2720    /*
2721     * DO NOT add a "default" clause here. Without it the compiler will
2722     * complain if an instruction is missing (which is desirable).
2723     */
2724  }  // end - switch (dec_insn.opcode)
2725
2726  if (have_pending_hard_failure_) {
2727    if (Runtime::Current()->IsCompiler()) {
2728      /* When compiling, check that the last failure is a hard failure */
2729      CHECK_EQ(failures_[failures_.size() - 1], VERIFY_ERROR_BAD_CLASS_HARD);
2730    }
2731    /* immediate failure, reject class */
2732    info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_);
2733    return false;
2734  } else if (have_pending_runtime_throw_failure_) {
2735    /* checking interpreter will throw, mark following code as unreachable */
2736    opcode_flags = Instruction::kThrow;
2737  }
2738  /*
2739   * If we didn't just set the result register, clear it out. This ensures that you can only use
2740   * "move-result" immediately after the result is set. (We could check this statically, but it's
2741   * not expensive and it makes our debugging output cleaner.)
2742   */
2743  if (!just_set_result) {
2744    work_line_->SetResultTypeToUnknown(this);
2745  }
2746
2747
2748
2749  /*
2750   * Handle "branch". Tag the branch target.
2751   *
2752   * NOTE: instructions like Instruction::EQZ provide information about the
2753   * state of the register when the branch is taken or not taken. For example,
2754   * somebody could get a reference field, check it for zero, and if the
2755   * branch is taken immediately store that register in a boolean field
2756   * since the value is known to be zero. We do not currently account for
2757   * that, and will reject the code.
2758   *
2759   * TODO: avoid re-fetching the branch target
2760   */
2761  if ((opcode_flags & Instruction::kBranch) != 0) {
2762    bool isConditional, selfOkay;
2763    if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) {
2764      /* should never happen after static verification */
2765      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch";
2766      return false;
2767    }
2768    DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0);
2769    if (!CheckNotMoveException(code_item_->insns_, work_insn_idx_ + branch_target)) {
2770      return false;
2771    }
2772    /* update branch target, set "changed" if appropriate */
2773    if (nullptr != branch_line.get()) {
2774      if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) {
2775        return false;
2776      }
2777    } else {
2778      if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) {
2779        return false;
2780      }
2781    }
2782  }
2783
2784  /*
2785   * Handle "switch". Tag all possible branch targets.
2786   *
2787   * We've already verified that the table is structurally sound, so we
2788   * just need to walk through and tag the targets.
2789   */
2790  if ((opcode_flags & Instruction::kSwitch) != 0) {
2791    int offset_to_switch = insns[1] | (((int32_t) insns[2]) << 16);
2792    const uint16_t* switch_insns = insns + offset_to_switch;
2793    int switch_count = switch_insns[1];
2794    int offset_to_targets, targ;
2795
2796    if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
2797      /* 0 = sig, 1 = count, 2/3 = first key */
2798      offset_to_targets = 4;
2799    } else {
2800      /* 0 = sig, 1 = count, 2..count * 2 = keys */
2801      DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH);
2802      offset_to_targets = 2 + 2 * switch_count;
2803    }
2804
2805    /* verify each switch target */
2806    for (targ = 0; targ < switch_count; targ++) {
2807      int offset;
2808      uint32_t abs_offset;
2809
2810      /* offsets are 32-bit, and only partly endian-swapped */
2811      offset = switch_insns[offset_to_targets + targ * 2] |
2812         (((int32_t) switch_insns[offset_to_targets + targ * 2 + 1]) << 16);
2813      abs_offset = work_insn_idx_ + offset;
2814      DCHECK_LT(abs_offset, code_item_->insns_size_in_code_units_);
2815      if (!CheckNotMoveException(code_item_->insns_, abs_offset)) {
2816        return false;
2817      }
2818      if (!UpdateRegisters(abs_offset, work_line_.get(), false)) {
2819        return false;
2820      }
2821    }
2822  }
2823
2824  /*
2825   * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a
2826   * "try" block when they throw, control transfers out of the method.)
2827   */
2828  if ((opcode_flags & Instruction::kThrow) != 0 && insn_flags_[work_insn_idx_].IsInTry()) {
2829    bool has_catch_all_handler = false;
2830    CatchHandlerIterator iterator(*code_item_, work_insn_idx_);
2831
2832    // Need the linker to try and resolve the handled class to check if it's Throwable.
2833    ClassLinker* linker = Runtime::Current()->GetClassLinker();
2834
2835    for (; iterator.HasNext(); iterator.Next()) {
2836      uint16_t handler_type_idx = iterator.GetHandlerTypeIndex();
2837      if (handler_type_idx == DexFile::kDexNoIndex16) {
2838        has_catch_all_handler = true;
2839      } else {
2840        // It is also a catch-all if it is java.lang.Throwable.
2841        mirror::Class* klass = linker->ResolveType(*dex_file_, handler_type_idx, dex_cache_,
2842                                                   class_loader_);
2843        if (klass != nullptr) {
2844          if (klass == mirror::Throwable::GetJavaLangThrowable()) {
2845            has_catch_all_handler = true;
2846          }
2847        } else {
2848          // Clear exception.
2849          DCHECK(self_->IsExceptionPending());
2850          self_->ClearException();
2851        }
2852      }
2853      /*
2854       * Merge registers into the "catch" block. We want to use the "savedRegs" rather than
2855       * "work_regs", because at runtime the exception will be thrown before the instruction
2856       * modifies any registers.
2857       */
2858      if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) {
2859        return false;
2860      }
2861    }
2862
2863    /*
2864     * If the monitor stack depth is nonzero, there must be a "catch all" handler for this
2865     * instruction. This does apply to monitor-exit because of async exception handling.
2866     */
2867    if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) {
2868      /*
2869       * The state in work_line reflects the post-execution state. If the current instruction is a
2870       * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws,
2871       * it will do so before grabbing the lock).
2872       */
2873      if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) {
2874        Fail(VERIFY_ERROR_BAD_CLASS_HARD)
2875            << "expected to be within a catch-all for an instruction where a monitor is held";
2876        return false;
2877      }
2878    }
2879  }
2880
2881  /* Handle "continue". Tag the next consecutive instruction.
2882   *  Note: Keep the code handling "continue" case below the "branch" and "switch" cases,
2883   *        because it changes work_line_ when performing peephole optimization
2884   *        and this change should not be used in those cases.
2885   */
2886  if ((opcode_flags & Instruction::kContinue) != 0) {
2887    DCHECK_EQ(Instruction::At(code_item_->insns_ + work_insn_idx_), inst);
2888    uint32_t next_insn_idx = work_insn_idx_ + inst->SizeInCodeUnits();
2889    if (next_insn_idx >= code_item_->insns_size_in_code_units_) {
2890      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area";
2891      return false;
2892    }
2893    // The only way to get to a move-exception instruction is to get thrown there. Make sure the
2894    // next instruction isn't one.
2895    if (!CheckNotMoveException(code_item_->insns_, next_insn_idx)) {
2896      return false;
2897    }
2898    if (nullptr != fallthrough_line.get()) {
2899      // Make workline consistent with fallthrough computed from peephole optimization.
2900      work_line_->CopyFromLine(fallthrough_line.get());
2901    }
2902    if (insn_flags_[next_insn_idx].IsReturn()) {
2903      // For returns we only care about the operand to the return, all other registers are dead.
2904      const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn_idx);
2905      Instruction::Code opcode = ret_inst->Opcode();
2906      if ((opcode == Instruction::RETURN_VOID) || (opcode == Instruction::RETURN_VOID_BARRIER)) {
2907        work_line_->MarkAllRegistersAsConflicts(this);
2908      } else {
2909        if (opcode == Instruction::RETURN_WIDE) {
2910          work_line_->MarkAllRegistersAsConflictsExceptWide(this, ret_inst->VRegA_11x());
2911        } else {
2912          work_line_->MarkAllRegistersAsConflictsExcept(this, ret_inst->VRegA_11x());
2913        }
2914      }
2915    }
2916    RegisterLine* next_line = reg_table_.GetLine(next_insn_idx);
2917    if (next_line != nullptr) {
2918      // Merge registers into what we have for the next instruction, and set the "changed" flag if
2919      // needed. If the merge changes the state of the registers then the work line will be
2920      // updated.
2921      if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) {
2922        return false;
2923      }
2924    } else {
2925      /*
2926       * We're not recording register data for the next instruction, so we don't know what the
2927       * prior state was. We have to assume that something has changed and re-evaluate it.
2928       */
2929      insn_flags_[next_insn_idx].SetChanged();
2930    }
2931  }
2932
2933  /* If we're returning from the method, make sure monitor stack is empty. */
2934  if ((opcode_flags & Instruction::kReturn) != 0) {
2935    if (!work_line_->VerifyMonitorStackEmpty(this)) {
2936      return false;
2937    }
2938  }
2939
2940  /*
2941   * Update start_guess. Advance to the next instruction of that's
2942   * possible, otherwise use the branch target if one was found. If
2943   * neither of those exists we're in a return or throw; leave start_guess
2944   * alone and let the caller sort it out.
2945   */
2946  if ((opcode_flags & Instruction::kContinue) != 0) {
2947    DCHECK_EQ(Instruction::At(code_item_->insns_ + work_insn_idx_), inst);
2948    *start_guess = work_insn_idx_ + inst->SizeInCodeUnits();
2949  } else if ((opcode_flags & Instruction::kBranch) != 0) {
2950    /* we're still okay if branch_target is zero */
2951    *start_guess = work_insn_idx_ + branch_target;
2952  }
2953
2954  DCHECK_LT(*start_guess, code_item_->insns_size_in_code_units_);
2955  DCHECK(insn_flags_[*start_guess].IsOpcode());
2956
2957  return true;
2958}  // NOLINT(readability/fn_size)
2959
2960const RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) {
2961  const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
2962  const RegType& referrer = GetDeclaringClass();
2963  mirror::Class* klass = dex_cache_->GetResolvedType(class_idx);
2964  const RegType& result = klass != nullptr ?
2965      reg_types_.FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()) :
2966      reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
2967  if (result.IsConflict()) {
2968    Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor
2969        << "' in " << referrer;
2970    return result;
2971  }
2972  if (klass == nullptr && !result.IsUnresolvedTypes()) {
2973    dex_cache_->SetResolvedType(class_idx, result.GetClass());
2974  }
2975  // Check if access is allowed. Unresolved types use xxxWithAccessCheck to
2976  // check at runtime if access is allowed and so pass here. If result is
2977  // primitive, skip the access check.
2978  if (result.IsNonZeroReferenceTypes() && !result.IsUnresolvedTypes() &&
2979      !referrer.IsUnresolvedTypes() && !referrer.CanAccess(result)) {
2980    Fail(VERIFY_ERROR_ACCESS_CLASS) << "illegal class access: '"
2981                                    << referrer << "' -> '" << result << "'";
2982  }
2983  return result;
2984}
2985
2986const RegType& MethodVerifier::GetCaughtExceptionType() {
2987  const RegType* common_super = nullptr;
2988  if (code_item_->tries_size_ != 0) {
2989    const byte* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
2990    uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
2991    for (uint32_t i = 0; i < handlers_size; i++) {
2992      CatchHandlerIterator iterator(handlers_ptr);
2993      for (; iterator.HasNext(); iterator.Next()) {
2994        if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) {
2995          if (iterator.GetHandlerTypeIndex() == DexFile::kDexNoIndex16) {
2996            common_super = &reg_types_.JavaLangThrowable(false);
2997          } else {
2998            const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex());
2999            if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception)) {
3000              if (exception.IsUnresolvedTypes()) {
3001                // We don't know enough about the type. Fail here and let runtime handle it.
3002                Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception;
3003                return exception;
3004              } else {
3005                Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception;
3006                return reg_types_.Conflict();
3007              }
3008            } else if (common_super == nullptr) {
3009              common_super = &exception;
3010            } else if (common_super->Equals(exception)) {
3011              // odd case, but nothing to do
3012            } else {
3013              common_super = &common_super->Merge(exception, &reg_types_);
3014              CHECK(reg_types_.JavaLangThrowable(false).IsAssignableFrom(*common_super));
3015            }
3016          }
3017        }
3018      }
3019      handlers_ptr = iterator.EndDataPointer();
3020    }
3021  }
3022  if (common_super == nullptr) {
3023    /* no catch blocks, or no catches with classes we can find */
3024    Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unable to find exception handler";
3025    return reg_types_.Conflict();
3026  }
3027  return *common_super;
3028}
3029
3030mirror::ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_method_idx,
3031                                                               MethodType method_type) {
3032  const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
3033  const RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
3034  if (klass_type.IsConflict()) {
3035    std::string append(" in attempt to access method ");
3036    append += dex_file_->GetMethodName(method_id);
3037    AppendToLastFailMessage(append);
3038    return nullptr;
3039  }
3040  if (klass_type.IsUnresolvedTypes()) {
3041    return nullptr;  // Can't resolve Class so no more to do here
3042  }
3043  mirror::Class* klass = klass_type.GetClass();
3044  const RegType& referrer = GetDeclaringClass();
3045  mirror::ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx);
3046  if (res_method == nullptr) {
3047    const char* name = dex_file_->GetMethodName(method_id);
3048    const Signature signature = dex_file_->GetMethodSignature(method_id);
3049
3050    if (method_type == METHOD_DIRECT || method_type == METHOD_STATIC) {
3051      res_method = klass->FindDirectMethod(name, signature);
3052    } else if (method_type == METHOD_INTERFACE) {
3053      res_method = klass->FindInterfaceMethod(name, signature);
3054    } else {
3055      res_method = klass->FindVirtualMethod(name, signature);
3056    }
3057    if (res_method != nullptr) {
3058      dex_cache_->SetResolvedMethod(dex_method_idx, res_method);
3059    } else {
3060      // If a virtual or interface method wasn't found with the expected type, look in
3061      // the direct methods. This can happen when the wrong invoke type is used or when
3062      // a class has changed, and will be flagged as an error in later checks.
3063      if (method_type == METHOD_INTERFACE || method_type == METHOD_VIRTUAL) {
3064        res_method = klass->FindDirectMethod(name, signature);
3065      }
3066      if (res_method == nullptr) {
3067        Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method "
3068                                     << PrettyDescriptor(klass) << "." << name
3069                                     << " " << signature;
3070        return nullptr;
3071      }
3072    }
3073  }
3074  // Make sure calls to constructors are "direct". There are additional restrictions but we don't
3075  // enforce them here.
3076  if (res_method->IsConstructor() && method_type != METHOD_DIRECT) {
3077    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor "
3078                                      << PrettyMethod(res_method);
3079    return nullptr;
3080  }
3081  // Disallow any calls to class initializers.
3082  if (res_method->IsClassInitializer()) {
3083    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer "
3084                                      << PrettyMethod(res_method);
3085    return nullptr;
3086  }
3087  // Check if access is allowed.
3088  if (!referrer.CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
3089    Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call " << PrettyMethod(res_method)
3090                                     << " from " << referrer << ")";
3091    return res_method;
3092  }
3093  // Check that invoke-virtual and invoke-super are not used on private methods of the same class.
3094  if (res_method->IsPrivate() && method_type == METHOD_VIRTUAL) {
3095    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method "
3096                                      << PrettyMethod(res_method);
3097    return nullptr;
3098  }
3099  // Check that interface methods match interface classes.
3100  if (klass->IsInterface() && method_type != METHOD_INTERFACE) {
3101    Fail(VERIFY_ERROR_CLASS_CHANGE) << "non-interface method " << PrettyMethod(res_method)
3102                                    << " is in an interface class " << PrettyClass(klass);
3103    return nullptr;
3104  } else if (!klass->IsInterface() && method_type == METHOD_INTERFACE) {
3105    Fail(VERIFY_ERROR_CLASS_CHANGE) << "interface method " << PrettyMethod(res_method)
3106                                    << " is in a non-interface class " << PrettyClass(klass);
3107    return nullptr;
3108  }
3109  // See if the method type implied by the invoke instruction matches the access flags for the
3110  // target method.
3111  if ((method_type == METHOD_DIRECT && !res_method->IsDirect()) ||
3112      (method_type == METHOD_STATIC && !res_method->IsStatic()) ||
3113      ((method_type == METHOD_VIRTUAL || method_type == METHOD_INTERFACE) && res_method->IsDirect())
3114      ) {
3115    Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method "
3116                                       " type of " << PrettyMethod(res_method);
3117    return nullptr;
3118  }
3119  return res_method;
3120}
3121
3122template <class T>
3123mirror::ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(T* it, const Instruction* inst,
3124                                                                    MethodType method_type,
3125                                                                    bool is_range,
3126                                                                    mirror::ArtMethod* res_method) {
3127  // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
3128  // match the call to the signature. Also, we might be calling through an abstract method
3129  // definition (which doesn't have register count values).
3130  const size_t expected_args = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
3131  /* caught by static verifier */
3132  DCHECK(is_range || expected_args <= 5);
3133  if (expected_args > code_item_->outs_size_) {
3134    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
3135        << ") exceeds outsSize (" << code_item_->outs_size_ << ")";
3136    return nullptr;
3137  }
3138
3139  uint32_t arg[5];
3140  if (!is_range) {
3141    inst->GetVarArgs(arg);
3142  }
3143  uint32_t sig_registers = 0;
3144
3145  /*
3146   * Check the "this" argument, which must be an instance of the class that declared the method.
3147   * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
3148   * rigorous check here (which is okay since we have to do it at runtime).
3149   */
3150  if (method_type != METHOD_STATIC) {
3151    const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst, is_range);
3152    if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
3153      CHECK(have_pending_hard_failure_);
3154      return nullptr;
3155    }
3156    if (actual_arg_type.IsUninitializedReference()) {
3157      if (res_method) {
3158        if (!res_method->IsConstructor()) {
3159          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
3160          return nullptr;
3161        }
3162      } else {
3163        // Check whether the name of the called method is "<init>"
3164        const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3165        if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) {
3166          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
3167          return nullptr;
3168        }
3169      }
3170    }
3171    if (method_type != METHOD_INTERFACE && !actual_arg_type.IsZero()) {
3172      const RegType* res_method_class;
3173      if (res_method != nullptr) {
3174        mirror::Class* klass = res_method->GetDeclaringClass();
3175        std::string temp;
3176        res_method_class = &reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
3177                                                 klass->CannotBeAssignedFromOtherTypes());
3178      } else {
3179        const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3180        const uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
3181        res_method_class = &reg_types_.FromDescriptor(GetClassLoader(),
3182                                                      dex_file_->StringByTypeIdx(class_idx),
3183                                                      false);
3184      }
3185      if (!res_method_class->IsAssignableFrom(actual_arg_type)) {
3186        Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS:
3187            VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
3188                << "' not instance of '" << *res_method_class << "'";
3189        // Continue on soft failures. We need to find possible hard failures to avoid problems in
3190        // the compiler.
3191        if (have_pending_hard_failure_) {
3192          return nullptr;
3193        }
3194      }
3195    }
3196    sig_registers = 1;
3197  }
3198
3199  for ( ; it->HasNext(); it->Next()) {
3200    if (sig_registers >= expected_args) {
3201      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() <<
3202          " arguments, found " << sig_registers << " or more.";
3203      return nullptr;
3204    }
3205
3206    const char* param_descriptor = it->GetDescriptor();
3207
3208    if (param_descriptor == nullptr) {
3209      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation because of missing signature "
3210          "component";
3211      return nullptr;
3212    }
3213
3214    const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), param_descriptor, false);
3215    uint32_t get_reg = is_range ? inst->VRegC_3rc() + static_cast<uint32_t>(sig_registers) :
3216        arg[sig_registers];
3217    if (reg_type.IsIntegralTypes()) {
3218      const RegType& src_type = work_line_->GetRegisterType(this, get_reg);
3219      if (!src_type.IsIntegralTypes()) {
3220        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type
3221            << " but expected " << reg_type;
3222        return res_method;
3223      }
3224    } else if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) {
3225      // Continue on soft failures. We need to find possible hard failures to avoid problems in the
3226      // compiler.
3227      if (have_pending_hard_failure_) {
3228        return res_method;
3229      }
3230    }
3231    sig_registers += reg_type.IsLongOrDoubleTypes() ?  2 : 1;
3232  }
3233  if (expected_args != sig_registers) {
3234    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args <<
3235        " arguments, found " << sig_registers;
3236    return nullptr;
3237  }
3238  return res_method;
3239}
3240
3241void MethodVerifier::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst,
3242                                                          MethodType method_type,
3243                                                          bool is_range) {
3244  // As the method may not have been resolved, make this static check against what we expect.
3245  // The main reason for this code block is to fail hard when we find an illegal use, e.g.,
3246  // wrong number of arguments or wrong primitive types, even if the method could not be resolved.
3247  const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3248  DexFileParameterIterator it(*dex_file_,
3249                              dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_));
3250  VerifyInvocationArgsFromIterator<DexFileParameterIterator>(&it, inst, method_type, is_range,
3251                                                             nullptr);
3252}
3253
3254class MethodParamListDescriptorIterator {
3255 public:
3256  explicit MethodParamListDescriptorIterator(mirror::ArtMethod* res_method) :
3257      res_method_(res_method), pos_(0), params_(res_method->GetParameterTypeList()),
3258      params_size_(params_ == nullptr ? 0 : params_->Size()) {
3259  }
3260
3261  bool HasNext() {
3262    return pos_ < params_size_;
3263  }
3264
3265  void Next() {
3266    ++pos_;
3267  }
3268
3269  const char* GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3270    return res_method_->GetTypeDescriptorFromTypeIdx(params_->GetTypeItem(pos_).type_idx_);
3271  }
3272
3273 private:
3274  mirror::ArtMethod* res_method_;
3275  size_t pos_;
3276  const DexFile::TypeList* params_;
3277  const size_t params_size_;
3278};
3279
3280mirror::ArtMethod* MethodVerifier::VerifyInvocationArgs(const Instruction* inst,
3281                                                             MethodType method_type,
3282                                                             bool is_range,
3283                                                             bool is_super) {
3284  // Resolve the method. This could be an abstract or concrete method depending on what sort of call
3285  // we're making.
3286  const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3287
3288  mirror::ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type);
3289  if (res_method == nullptr) {  // error or class is unresolved
3290    // Check what we can statically.
3291    if (!have_pending_hard_failure_) {
3292      VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
3293    }
3294    return nullptr;
3295  }
3296
3297  // If we're using invoke-super(method), make sure that the executing method's class' superclass
3298  // has a vtable entry for the target method.
3299  if (is_super) {
3300    DCHECK(method_type == METHOD_VIRTUAL);
3301    const RegType& super = GetDeclaringClass().GetSuperClass(&reg_types_);
3302    if (super.IsUnresolvedTypes()) {
3303      Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from "
3304                                   << PrettyMethod(dex_method_idx_, *dex_file_)
3305                                   << " to super " << PrettyMethod(res_method);
3306      return nullptr;
3307    }
3308    mirror::Class* super_klass = super.GetClass();
3309    if (res_method->GetMethodIndex() >= super_klass->GetVTableLength()) {
3310      Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
3311                                   << PrettyMethod(dex_method_idx_, *dex_file_)
3312                                   << " to super " << super
3313                                   << "." << res_method->GetName()
3314                                   << res_method->GetSignature();
3315      return nullptr;
3316    }
3317  }
3318
3319  // Process the target method's signature. This signature may or may not
3320  MethodParamListDescriptorIterator it(res_method);
3321  return VerifyInvocationArgsFromIterator<MethodParamListDescriptorIterator>(&it, inst, method_type,
3322                                                                             is_range, res_method);
3323}
3324
3325mirror::ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst,
3326                                                         RegisterLine* reg_line, bool is_range) {
3327  DCHECK(inst->Opcode() == Instruction::INVOKE_VIRTUAL_QUICK ||
3328         inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
3329  const RegType& actual_arg_type = reg_line->GetInvocationThis(this, inst, is_range);
3330  if (!actual_arg_type.HasClass()) {
3331    VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'";
3332    return nullptr;
3333  }
3334  mirror::Class* klass = actual_arg_type.GetClass();
3335  mirror::Class* dispatch_class;
3336  if (klass->IsInterface()) {
3337    // Derive Object.class from Class.class.getSuperclass().
3338    mirror::Class* object_klass = klass->GetClass()->GetSuperClass();
3339    CHECK(object_klass->IsObjectClass());
3340    dispatch_class = object_klass;
3341  } else {
3342    dispatch_class = klass;
3343  }
3344  CHECK(dispatch_class->HasVTable()) << PrettyDescriptor(dispatch_class);
3345  uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
3346  CHECK_LT(static_cast<int32_t>(vtable_index), dispatch_class->GetVTableLength())
3347      << PrettyDescriptor(klass);
3348  mirror::ArtMethod* res_method = dispatch_class->GetVTableEntry(vtable_index);
3349  CHECK(!self_->IsExceptionPending());
3350  return res_method;
3351}
3352
3353mirror::ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst,
3354                                                                bool is_range) {
3355  DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
3356  mirror::ArtMethod* res_method = GetQuickInvokedMethod(inst, work_line_.get(),
3357                                                             is_range);
3358  if (res_method == nullptr) {
3359    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer method from " << inst->Name();
3360    return nullptr;
3361  }
3362  CHECK(!res_method->IsDirect() && !res_method->IsStatic());
3363
3364  // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
3365  // match the call to the signature. Also, we might be calling through an abstract method
3366  // definition (which doesn't have register count values).
3367  const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst, is_range);
3368  if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
3369    return nullptr;
3370  }
3371  const size_t expected_args = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
3372  /* caught by static verifier */
3373  DCHECK(is_range || expected_args <= 5);
3374  if (expected_args > code_item_->outs_size_) {
3375    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
3376        << ") exceeds outsSize (" << code_item_->outs_size_ << ")";
3377    return nullptr;
3378  }
3379
3380  /*
3381   * Check the "this" argument, which must be an instance of the class that declared the method.
3382   * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
3383   * rigorous check here (which is okay since we have to do it at runtime).
3384   */
3385  if (actual_arg_type.IsUninitializedReference() && !res_method->IsConstructor()) {
3386    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
3387    return nullptr;
3388  }
3389  if (!actual_arg_type.IsZero()) {
3390    mirror::Class* klass = res_method->GetDeclaringClass();
3391    std::string temp;
3392    const RegType& res_method_class =
3393        reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
3394                             klass->CannotBeAssignedFromOtherTypes());
3395    if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
3396      Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS :
3397          VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
3398          << "' not instance of '" << res_method_class << "'";
3399      return nullptr;
3400    }
3401  }
3402  /*
3403   * Process the target method's signature. This signature may or may not
3404   * have been verified, so we can't assume it's properly formed.
3405   */
3406  const DexFile::TypeList* params = res_method->GetParameterTypeList();
3407  size_t params_size = params == nullptr ? 0 : params->Size();
3408  uint32_t arg[5];
3409  if (!is_range) {
3410    inst->GetVarArgs(arg);
3411  }
3412  size_t actual_args = 1;
3413  for (size_t param_index = 0; param_index < params_size; param_index++) {
3414    if (actual_args >= expected_args) {
3415      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invalid call to '" << PrettyMethod(res_method)
3416                                        << "'. Expected " << expected_args
3417                                         << " arguments, processing argument " << actual_args
3418                                        << " (where longs/doubles count twice).";
3419      return nullptr;
3420    }
3421    const char* descriptor =
3422        res_method->GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
3423    if (descriptor == nullptr) {
3424      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " << PrettyMethod(res_method)
3425                                        << " missing signature component";
3426      return nullptr;
3427    }
3428    const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
3429    uint32_t get_reg = is_range ? inst->VRegC_3rc() + actual_args : arg[actual_args];
3430    if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) {
3431      return res_method;
3432    }
3433    actual_args = reg_type.IsLongOrDoubleTypes() ? actual_args + 2 : actual_args + 1;
3434  }
3435  if (actual_args != expected_args) {
3436    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " << PrettyMethod(res_method)
3437              << " expected " << expected_args << " arguments, found " << actual_args;
3438    return nullptr;
3439  } else {
3440    return res_method;
3441  }
3442}
3443
3444void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) {
3445  uint32_t type_idx;
3446  if (!is_filled) {
3447    DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY);
3448    type_idx = inst->VRegC_22c();
3449  } else if (!is_range) {
3450    DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY);
3451    type_idx = inst->VRegB_35c();
3452  } else {
3453    DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE);
3454    type_idx = inst->VRegB_3rc();
3455  }
3456  const RegType& res_type = ResolveClassAndCheckAccess(type_idx);
3457  if (res_type.IsConflict()) {  // bad class
3458    DCHECK_NE(failures_.size(), 0U);
3459  } else {
3460    // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
3461    if (!res_type.IsArrayTypes()) {
3462      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type;
3463    } else if (!is_filled) {
3464      /* make sure "size" register is valid type */
3465      work_line_->VerifyRegisterType(this, inst->VRegB_22c(), reg_types_.Integer());
3466      /* set register type to array class */
3467      const RegType& precise_type = reg_types_.FromUninitialized(res_type);
3468      work_line_->SetRegisterType(this, inst->VRegA_22c(), precise_type);
3469    } else {
3470      // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
3471      // the list and fail. It's legal, if silly, for arg_count to be zero.
3472      const RegType& expected_type = reg_types_.GetComponentType(res_type, GetClassLoader());
3473      uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
3474      uint32_t arg[5];
3475      if (!is_range) {
3476        inst->GetVarArgs(arg);
3477      }
3478      for (size_t ui = 0; ui < arg_count; ui++) {
3479        uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui];
3480        if (!work_line_->VerifyRegisterType(this, get_reg, expected_type)) {
3481          work_line_->SetResultRegisterType(this, reg_types_.Conflict());
3482          return;
3483        }
3484      }
3485      // filled-array result goes into "result" register
3486      const RegType& precise_type = reg_types_.FromUninitialized(res_type);
3487      work_line_->SetResultRegisterType(this, precise_type);
3488    }
3489  }
3490}
3491
3492void MethodVerifier::VerifyAGet(const Instruction* inst,
3493                                const RegType& insn_type, bool is_primitive) {
3494  const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
3495  if (!index_type.IsArrayIndexTypes()) {
3496    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
3497  } else {
3498    const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
3499    if (array_type.IsZero()) {
3500      // Null array class; this code path will fail at runtime. Infer a merge-able type from the
3501      // instruction type. TODO: have a proper notion of bottom here.
3502      if (!is_primitive || insn_type.IsCategory1Types()) {
3503        // Reference or category 1
3504        work_line_->SetRegisterType(this, inst->VRegA_23x(), reg_types_.Zero());
3505      } else {
3506        // Category 2
3507        work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(),
3508                                        reg_types_.FromCat2ConstLo(0, false),
3509                                        reg_types_.FromCat2ConstHi(0, false));
3510      }
3511    } else if (!array_type.IsArrayTypes()) {
3512      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget";
3513    } else {
3514      /* verify the class */
3515      const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
3516      if (!component_type.IsReferenceTypes() && !is_primitive) {
3517        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
3518            << " source for aget-object";
3519      } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) {
3520        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
3521            << " source for category 1 aget";
3522      } else if (is_primitive && !insn_type.Equals(component_type) &&
3523                 !((insn_type.IsInteger() && component_type.IsFloat()) ||
3524                 (insn_type.IsLong() && component_type.IsDouble()))) {
3525        Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type
3526            << " incompatible with aget of type " << insn_type;
3527      } else {
3528        // Use knowledge of the field type which is stronger than the type inferred from the
3529        // instruction, which can't differentiate object types and ints from floats, longs from
3530        // doubles.
3531        if (!component_type.IsLowHalf()) {
3532          work_line_->SetRegisterType(this, inst->VRegA_23x(), component_type);
3533        } else {
3534          work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), component_type,
3535                                          component_type.HighHalf(&reg_types_));
3536        }
3537      }
3538    }
3539  }
3540}
3541
3542void MethodVerifier::VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type,
3543                                        const uint32_t vregA) {
3544  // Primitive assignability rules are weaker than regular assignability rules.
3545  bool instruction_compatible;
3546  bool value_compatible;
3547  const RegType& value_type = work_line_->GetRegisterType(this, vregA);
3548  if (target_type.IsIntegralTypes()) {
3549    instruction_compatible = target_type.Equals(insn_type);
3550    value_compatible = value_type.IsIntegralTypes();
3551  } else if (target_type.IsFloat()) {
3552    instruction_compatible = insn_type.IsInteger();  // no put-float, so expect put-int
3553    value_compatible = value_type.IsFloatTypes();
3554  } else if (target_type.IsLong()) {
3555    instruction_compatible = insn_type.IsLong();
3556    // Additional register check: this is not checked statically (as part of VerifyInstructions),
3557    // as target_type depends on the resolved type of the field.
3558    if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
3559      const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
3560      value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
3561    } else {
3562      value_compatible = false;
3563    }
3564  } else if (target_type.IsDouble()) {
3565    instruction_compatible = insn_type.IsLong();  // no put-double, so expect put-long
3566    // Additional register check: this is not checked statically (as part of VerifyInstructions),
3567    // as target_type depends on the resolved type of the field.
3568    if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
3569      const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
3570      value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
3571    } else {
3572      value_compatible = false;
3573    }
3574  } else {
3575    instruction_compatible = false;  // reference with primitive store
3576    value_compatible = false;  // unused
3577  }
3578  if (!instruction_compatible) {
3579    // This is a global failure rather than a class change failure as the instructions and
3580    // the descriptors for the type should have been consistent within the same file at
3581    // compile time.
3582    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
3583        << "' but expected type '" << target_type << "'";
3584    return;
3585  }
3586  if (!value_compatible) {
3587    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
3588        << " of type " << value_type << " but expected " << target_type << " for put";
3589    return;
3590  }
3591}
3592
3593void MethodVerifier::VerifyAPut(const Instruction* inst,
3594                                const RegType& insn_type, bool is_primitive) {
3595  const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
3596  if (!index_type.IsArrayIndexTypes()) {
3597    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
3598  } else {
3599    const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
3600    if (array_type.IsZero()) {
3601      // Null array type; this code path will fail at runtime. Infer a merge-able type from the
3602      // instruction type.
3603    } else if (!array_type.IsArrayTypes()) {
3604      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
3605    } else {
3606      const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
3607      const uint32_t vregA = inst->VRegA_23x();
3608      if (is_primitive) {
3609        VerifyPrimitivePut(component_type, insn_type, vregA);
3610      } else {
3611        if (!component_type.IsReferenceTypes()) {
3612          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
3613              << " source for aput-object";
3614        } else {
3615          // The instruction agrees with the type of array, confirm the value to be stored does too
3616          // Note: we use the instruction type (rather than the component type) for aput-object as
3617          // incompatible classes will be caught at runtime as an array store exception
3618          work_line_->VerifyRegisterType(this, vregA, insn_type);
3619        }
3620      }
3621    }
3622  }
3623}
3624
3625mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) {
3626  const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
3627  // Check access to class
3628  const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
3629  if (klass_type.IsConflict()) {  // bad class
3630    AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s",
3631                                         field_idx, dex_file_->GetFieldName(field_id),
3632                                         dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
3633    return nullptr;
3634  }
3635  if (klass_type.IsUnresolvedTypes()) {
3636    return nullptr;  // Can't resolve Class so no more to do here, will do checking at runtime.
3637  }
3638  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
3639  mirror::ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_,
3640                                                          class_loader_);
3641  if (field == nullptr) {
3642    VLOG(verifier) << "Unable to resolve static field " << field_idx << " ("
3643              << dex_file_->GetFieldName(field_id) << ") in "
3644              << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
3645    DCHECK(self_->IsExceptionPending());
3646    self_->ClearException();
3647    return nullptr;
3648  } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
3649                                                  field->GetAccessFlags())) {
3650    Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access static field " << PrettyField(field)
3651                                    << " from " << GetDeclaringClass();
3652    return nullptr;
3653  } else if (!field->IsStatic()) {
3654    Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << PrettyField(field) << " to be static";
3655    return nullptr;
3656  }
3657  return field;
3658}
3659
3660mirror::ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
3661  const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
3662  // Check access to class
3663  const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
3664  if (klass_type.IsConflict()) {
3665    AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s",
3666                                         field_idx, dex_file_->GetFieldName(field_id),
3667                                         dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
3668    return nullptr;
3669  }
3670  if (klass_type.IsUnresolvedTypes()) {
3671    return nullptr;  // Can't resolve Class so no more to do here
3672  }
3673  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
3674  mirror::ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_,
3675                                                          class_loader_);
3676  if (field == nullptr) {
3677    VLOG(verifier) << "Unable to resolve instance field " << field_idx << " ("
3678              << dex_file_->GetFieldName(field_id) << ") in "
3679              << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
3680    DCHECK(self_->IsExceptionPending());
3681    self_->ClearException();
3682    return nullptr;
3683  } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
3684                                                  field->GetAccessFlags())) {
3685    Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access instance field " << PrettyField(field)
3686                                    << " from " << GetDeclaringClass();
3687    return nullptr;
3688  } else if (field->IsStatic()) {
3689    Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << PrettyField(field)
3690                                    << " to not be static";
3691    return nullptr;
3692  } else if (obj_type.IsZero()) {
3693    // Cannot infer and check type, however, access will cause null pointer exception
3694    return field;
3695  } else if (!obj_type.IsReferenceTypes()) {
3696    // Trying to read a field from something that isn't a reference
3697    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
3698                                      << "non-reference type " << obj_type;
3699    return nullptr;
3700  } else {
3701    mirror::Class* klass = field->GetDeclaringClass();
3702    const RegType& field_klass =
3703        reg_types_.FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
3704                             klass, klass->CannotBeAssignedFromOtherTypes());
3705    if (obj_type.IsUninitializedTypes() &&
3706        (!IsConstructor() || GetDeclaringClass().Equals(obj_type) ||
3707            !field_klass.Equals(GetDeclaringClass()))) {
3708      // Field accesses through uninitialized references are only allowable for constructors where
3709      // the field is declared in this class
3710      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access instance field " << PrettyField(field)
3711                                        << " of a not fully initialized object within the context"
3712                                        << " of " << PrettyMethod(dex_method_idx_, *dex_file_);
3713      return nullptr;
3714    } else if (!field_klass.IsAssignableFrom(obj_type)) {
3715      // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class
3716      // of C1. For resolution to occur the declared class of the field must be compatible with
3717      // obj_type, we've discovered this wasn't so, so report the field didn't exist.
3718      Fail(VERIFY_ERROR_NO_FIELD) << "cannot access instance field " << PrettyField(field)
3719                                  << " from object of type " << obj_type;
3720      return nullptr;
3721    } else {
3722      return field;
3723    }
3724  }
3725}
3726
3727void MethodVerifier::VerifyISGet(const Instruction* inst, const RegType& insn_type,
3728                                 bool is_primitive, bool is_static) {
3729  uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
3730  mirror::ArtField* field;
3731  if (is_static) {
3732    field = GetStaticField(field_idx);
3733  } else {
3734    const RegType& object_type = work_line_->GetRegisterType(this, inst->VRegB_22c());
3735    field = GetInstanceField(object_type, field_idx);
3736  }
3737  const RegType* field_type = nullptr;
3738  if (field != nullptr) {
3739    mirror::Class* field_type_class;
3740    {
3741      StackHandleScope<1> hs(self_);
3742      HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
3743      field_type_class = FieldHelper(h_field).GetType(can_load_classes_);
3744    }
3745    if (field_type_class != nullptr) {
3746      field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
3747                                         field_type_class->CannotBeAssignedFromOtherTypes());
3748    } else {
3749      DCHECK(!can_load_classes_ || self_->IsExceptionPending());
3750      self_->ClearException();
3751    }
3752  }
3753  if (field_type == nullptr) {
3754    const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
3755    const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
3756    field_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
3757  }
3758  DCHECK(field_type != nullptr);
3759  const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
3760  if (is_primitive) {
3761    if (field_type->Equals(insn_type) ||
3762        (field_type->IsFloat() && insn_type.IsInteger()) ||
3763        (field_type->IsDouble() && insn_type.IsLong())) {
3764      // expected that read is of the correct primitive type or that int reads are reading
3765      // floats or long reads are reading doubles
3766    } else {
3767      // This is a global failure rather than a class change failure as the instructions and
3768      // the descriptors for the type should have been consistent within the same file at
3769      // compile time
3770      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
3771                                        << " to be of type '" << insn_type
3772                                        << "' but found type '" << *field_type << "' in get";
3773      return;
3774    }
3775  } else {
3776    if (!insn_type.IsAssignableFrom(*field_type)) {
3777      Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
3778                                        << " to be compatible with type '" << insn_type
3779                                        << "' but found type '" << *field_type
3780                                        << "' in Get-object";
3781      work_line_->SetRegisterType(this, vregA, reg_types_.Conflict());
3782      return;
3783    }
3784  }
3785  if (!field_type->IsLowHalf()) {
3786    work_line_->SetRegisterType(this, vregA, *field_type);
3787  } else {
3788    work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(&reg_types_));
3789  }
3790}
3791
3792void MethodVerifier::VerifyISPut(const Instruction* inst, const RegType& insn_type,
3793                                 bool is_primitive, bool is_static) {
3794  uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
3795  mirror::ArtField* field;
3796  if (is_static) {
3797    field = GetStaticField(field_idx);
3798  } else {
3799    const RegType& object_type = work_line_->GetRegisterType(this, inst->VRegB_22c());
3800    field = GetInstanceField(object_type, field_idx);
3801  }
3802  const RegType* field_type = nullptr;
3803  if (field != nullptr) {
3804    if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
3805      Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
3806                                      << " from other class " << GetDeclaringClass();
3807      return;
3808    }
3809    mirror::Class* field_type_class;
3810    {
3811      StackHandleScope<1> hs(self_);
3812      HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
3813      FieldHelper fh(h_field);
3814      field_type_class = fh.GetType(can_load_classes_);
3815    }
3816    if (field_type_class != nullptr) {
3817      field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
3818                                         field_type_class->CannotBeAssignedFromOtherTypes());
3819    } else {
3820      DCHECK(!can_load_classes_ || self_->IsExceptionPending());
3821      self_->ClearException();
3822    }
3823  }
3824  if (field_type == nullptr) {
3825    const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
3826    const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
3827    field_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
3828  }
3829  DCHECK(field_type != nullptr);
3830  const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
3831  if (is_primitive) {
3832    VerifyPrimitivePut(*field_type, insn_type, vregA);
3833  } else {
3834    if (!insn_type.IsAssignableFrom(*field_type)) {
3835      Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
3836                                        << " to be compatible with type '" << insn_type
3837                                        << "' but found type '" << *field_type
3838                                        << "' in put-object";
3839      return;
3840    }
3841    work_line_->VerifyRegisterType(this, vregA, *field_type);
3842  }
3843}
3844
3845mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
3846                                                      RegisterLine* reg_line) {
3847  DCHECK(inst->Opcode() == Instruction::IGET_QUICK ||
3848         inst->Opcode() == Instruction::IGET_WIDE_QUICK ||
3849         inst->Opcode() == Instruction::IGET_OBJECT_QUICK ||
3850         inst->Opcode() == Instruction::IPUT_QUICK ||
3851         inst->Opcode() == Instruction::IPUT_WIDE_QUICK ||
3852         inst->Opcode() == Instruction::IPUT_OBJECT_QUICK);
3853  const RegType& object_type = reg_line->GetRegisterType(this, inst->VRegB_22c());
3854  if (!object_type.HasClass()) {
3855    VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'";
3856    return nullptr;
3857  }
3858  uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
3859  mirror::ArtField* f = mirror::ArtField::FindInstanceFieldWithOffset(object_type.GetClass(),
3860                                                                      field_offset);
3861  if (f == nullptr) {
3862    VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
3863                   << "' from '" << PrettyDescriptor(object_type.GetClass()) << "'";
3864  }
3865  return f;
3866}
3867
3868void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& insn_type,
3869                                     bool is_primitive) {
3870  DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
3871  mirror::ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
3872  if (field == nullptr) {
3873    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name();
3874    return;
3875  }
3876  mirror::Class* field_type_class;
3877  {
3878    StackHandleScope<1> hs(self_);
3879    HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
3880    FieldHelper fh(h_field);
3881    field_type_class = fh.GetType(can_load_classes_);
3882  }
3883  const RegType* field_type;
3884  if (field_type_class != nullptr) {
3885    field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
3886                                       field_type_class->CannotBeAssignedFromOtherTypes());
3887  } else {
3888    DCHECK(!can_load_classes_ || self_->IsExceptionPending());
3889    self_->ClearException();
3890    field_type = &reg_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
3891                                            field->GetTypeDescriptor(), false);
3892  }
3893  DCHECK(field_type != nullptr);
3894  const uint32_t vregA = inst->VRegA_22c();
3895  if (is_primitive) {
3896    if (field_type->Equals(insn_type) ||
3897        (field_type->IsFloat() && insn_type.IsIntegralTypes()) ||
3898        (field_type->IsDouble() && insn_type.IsLongTypes())) {
3899      // expected that read is of the correct primitive type or that int reads are reading
3900      // floats or long reads are reading doubles
3901    } else {
3902      // This is a global failure rather than a class change failure as the instructions and
3903      // the descriptors for the type should have been consistent within the same file at
3904      // compile time
3905      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
3906                                        << " to be of type '" << insn_type
3907                                        << "' but found type '" << *field_type << "' in Get";
3908      return;
3909    }
3910  } else {
3911    if (!insn_type.IsAssignableFrom(*field_type)) {
3912      Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
3913                                        << " to be compatible with type '" << insn_type
3914                                        << "' but found type '" << *field_type
3915                                        << "' in get-object";
3916      work_line_->SetRegisterType(this, vregA, reg_types_.Conflict());
3917      return;
3918    }
3919  }
3920  if (!field_type->IsLowHalf()) {
3921    work_line_->SetRegisterType(this, vregA, *field_type);
3922  } else {
3923    work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(&reg_types_));
3924  }
3925}
3926
3927void MethodVerifier::VerifyIPutQuick(const Instruction* inst, const RegType& insn_type,
3928                                     bool is_primitive) {
3929  DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
3930  mirror::ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
3931  if (field == nullptr) {
3932    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name();
3933    return;
3934  }
3935  const char* descriptor = field->GetTypeDescriptor();
3936  mirror::ClassLoader* loader = field->GetDeclaringClass()->GetClassLoader();
3937  const RegType& field_type = reg_types_.FromDescriptor(loader, descriptor, false);
3938  if (field != nullptr) {
3939    if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
3940      Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
3941                                      << " from other class " << GetDeclaringClass();
3942      return;
3943    }
3944  }
3945  const uint32_t vregA = inst->VRegA_22c();
3946  if (is_primitive) {
3947    // Primitive field assignability rules are weaker than regular assignability rules
3948    bool instruction_compatible;
3949    bool value_compatible;
3950    const RegType& value_type = work_line_->GetRegisterType(this, vregA);
3951    if (field_type.IsIntegralTypes()) {
3952      instruction_compatible = insn_type.IsIntegralTypes();
3953      value_compatible = value_type.IsIntegralTypes();
3954    } else if (field_type.IsFloat()) {
3955      instruction_compatible = insn_type.IsInteger();  // no [is]put-float, so expect [is]put-int
3956      value_compatible = value_type.IsFloatTypes();
3957    } else if (field_type.IsLong()) {
3958      instruction_compatible = insn_type.IsLong();
3959      value_compatible = value_type.IsLongTypes();
3960    } else if (field_type.IsDouble()) {
3961      instruction_compatible = insn_type.IsLong();  // no [is]put-double, so expect [is]put-long
3962      value_compatible = value_type.IsDoubleTypes();
3963    } else {
3964      instruction_compatible = false;  // reference field with primitive store
3965      value_compatible = false;  // unused
3966    }
3967    if (!instruction_compatible) {
3968      // This is a global failure rather than a class change failure as the instructions and
3969      // the descriptors for the type should have been consistent within the same file at
3970      // compile time
3971      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
3972                                        << " to be of type '" << insn_type
3973                                        << "' but found type '" << field_type
3974                                        << "' in put";
3975      return;
3976    }
3977    if (!value_compatible) {
3978      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
3979          << " of type " << value_type
3980          << " but expected " << field_type
3981          << " for store to " << PrettyField(field) << " in put";
3982      return;
3983    }
3984  } else {
3985    if (!insn_type.IsAssignableFrom(field_type)) {
3986      Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
3987                                        << " to be compatible with type '" << insn_type
3988                                        << "' but found type '" << field_type
3989                                        << "' in put-object";
3990      return;
3991    }
3992    work_line_->VerifyRegisterType(this, vregA, field_type);
3993  }
3994}
3995
3996bool MethodVerifier::CheckNotMoveException(const uint16_t* insns, int insn_idx) {
3997  if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) {
3998    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception";
3999    return false;
4000  }
4001  return true;
4002}
4003
4004bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line,
4005                                     bool update_merge_line) {
4006  bool changed = true;
4007  RegisterLine* target_line = reg_table_.GetLine(next_insn);
4008  if (!insn_flags_[next_insn].IsVisitedOrChanged()) {
4009    /*
4010     * We haven't processed this instruction before, and we haven't touched the registers here, so
4011     * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the
4012     * only way a register can transition out of "unknown", so this is not just an optimization.)
4013     */
4014    if (!insn_flags_[next_insn].IsReturn()) {
4015      target_line->CopyFromLine(merge_line);
4016    } else {
4017      // Verify that the monitor stack is empty on return.
4018      if (!merge_line->VerifyMonitorStackEmpty(this)) {
4019        return false;
4020      }
4021      // For returns we only care about the operand to the return, all other registers are dead.
4022      // Initialize them as conflicts so they don't add to GC and deoptimization information.
4023      const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn);
4024      Instruction::Code opcode = ret_inst->Opcode();
4025      if ((opcode == Instruction::RETURN_VOID) || (opcode == Instruction::RETURN_VOID_BARRIER)) {
4026        target_line->MarkAllRegistersAsConflicts(this);
4027      } else {
4028        target_line->CopyFromLine(merge_line);
4029        if (opcode == Instruction::RETURN_WIDE) {
4030          target_line->MarkAllRegistersAsConflictsExceptWide(this, ret_inst->VRegA_11x());
4031        } else {
4032          target_line->MarkAllRegistersAsConflictsExcept(this, ret_inst->VRegA_11x());
4033        }
4034      }
4035    }
4036  } else {
4037    std::unique_ptr<RegisterLine> copy(gDebugVerify ?
4038                                 RegisterLine::Create(target_line->NumRegs(), this) :
4039                                 nullptr);
4040    if (gDebugVerify) {
4041      copy->CopyFromLine(target_line);
4042    }
4043    changed = target_line->MergeRegisters(this, merge_line);
4044    if (have_pending_hard_failure_) {
4045      return false;
4046    }
4047    if (gDebugVerify && changed) {
4048      LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]"
4049                      << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n"
4050                      << copy->Dump(this) << "  MERGE\n"
4051                      << merge_line->Dump(this) << "  ==\n"
4052                      << target_line->Dump(this) << "\n";
4053    }
4054    if (update_merge_line && changed) {
4055      merge_line->CopyFromLine(target_line);
4056    }
4057  }
4058  if (changed) {
4059    insn_flags_[next_insn].SetChanged();
4060  }
4061  return true;
4062}
4063
4064InstructionFlags* MethodVerifier::CurrentInsnFlags() {
4065  return &insn_flags_[work_insn_idx_];
4066}
4067
4068const RegType& MethodVerifier::GetMethodReturnType() {
4069  if (return_type_ == nullptr) {
4070    if (mirror_method_.Get() != nullptr) {
4071      StackHandleScope<1> hs(self_);
4072      mirror::Class* return_type_class =
4073          MethodHelper(hs.NewHandle(mirror_method_.Get())).GetReturnType(can_load_classes_);
4074      if (return_type_class != nullptr) {
4075        return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
4076                                             return_type_class,
4077                                             return_type_class->CannotBeAssignedFromOtherTypes());
4078      } else {
4079        DCHECK(!can_load_classes_ || self_->IsExceptionPending());
4080        self_->ClearException();
4081      }
4082    }
4083    if (return_type_ == nullptr) {
4084      const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
4085      const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id);
4086      uint16_t return_type_idx = proto_id.return_type_idx_;
4087      const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx));
4088      return_type_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
4089    }
4090  }
4091  return *return_type_;
4092}
4093
4094const RegType& MethodVerifier::GetDeclaringClass() {
4095  if (declaring_class_ == nullptr) {
4096    const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
4097    const char* descriptor
4098        = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
4099    if (mirror_method_.Get() != nullptr) {
4100      mirror::Class* klass = mirror_method_->GetDeclaringClass();
4101      declaring_class_ = &reg_types_.FromClass(descriptor, klass,
4102                                               klass->CannotBeAssignedFromOtherTypes());
4103    } else {
4104      declaring_class_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
4105    }
4106  }
4107  return *declaring_class_;
4108}
4109
4110std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) {
4111  RegisterLine* line = reg_table_.GetLine(dex_pc);
4112  DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc);
4113  std::vector<int32_t> result;
4114  for (size_t i = 0; i < line->NumRegs(); ++i) {
4115    const RegType& type = line->GetRegisterType(this, i);
4116    if (type.IsConstant()) {
4117      result.push_back(type.IsPreciseConstant() ? kConstant : kImpreciseConstant);
4118      const ConstantType* const_val = down_cast<const ConstantType*>(&type);
4119      result.push_back(const_val->ConstantValue());
4120    } else if (type.IsConstantLo()) {
4121      result.push_back(type.IsPreciseConstantLo() ? kConstant : kImpreciseConstant);
4122      const ConstantType* const_val = down_cast<const ConstantType*>(&type);
4123      result.push_back(const_val->ConstantValueLo());
4124    } else if (type.IsConstantHi()) {
4125      result.push_back(type.IsPreciseConstantHi() ? kConstant : kImpreciseConstant);
4126      const ConstantType* const_val = down_cast<const ConstantType*>(&type);
4127      result.push_back(const_val->ConstantValueHi());
4128    } else if (type.IsIntegralTypes()) {
4129      result.push_back(kIntVReg);
4130      result.push_back(0);
4131    } else if (type.IsFloat()) {
4132      result.push_back(kFloatVReg);
4133      result.push_back(0);
4134    } else if (type.IsLong()) {
4135      result.push_back(kLongLoVReg);
4136      result.push_back(0);
4137      result.push_back(kLongHiVReg);
4138      result.push_back(0);
4139      ++i;
4140    } else if (type.IsDouble()) {
4141      result.push_back(kDoubleLoVReg);
4142      result.push_back(0);
4143      result.push_back(kDoubleHiVReg);
4144      result.push_back(0);
4145      ++i;
4146    } else if (type.IsUndefined() || type.IsConflict() || type.IsHighHalf()) {
4147      result.push_back(kUndefined);
4148      result.push_back(0);
4149    } else {
4150      CHECK(type.IsNonZeroReferenceTypes());
4151      result.push_back(kReferenceVReg);
4152      result.push_back(0);
4153    }
4154  }
4155  return result;
4156}
4157
4158const RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) {
4159  if (precise) {
4160    // Precise constant type.
4161    return reg_types_.FromCat1Const(value, true);
4162  } else {
4163    // Imprecise constant type.
4164    if (value < -32768) {
4165      return reg_types_.IntConstant();
4166    } else if (value < -128) {
4167      return reg_types_.ShortConstant();
4168    } else if (value < 0) {
4169      return reg_types_.ByteConstant();
4170    } else if (value == 0) {
4171      return reg_types_.Zero();
4172    } else if (value == 1) {
4173      return reg_types_.One();
4174    } else if (value < 128) {
4175      return reg_types_.PosByteConstant();
4176    } else if (value < 32768) {
4177      return reg_types_.PosShortConstant();
4178    } else if (value < 65536) {
4179      return reg_types_.CharConstant();
4180    } else {
4181      return reg_types_.IntConstant();
4182    }
4183  }
4184}
4185
4186void MethodVerifier::Init() {
4187  art::verifier::RegTypeCache::Init();
4188}
4189
4190void MethodVerifier::Shutdown() {
4191  verifier::RegTypeCache::ShutDown();
4192}
4193
4194void MethodVerifier::VisitStaticRoots(RootCallback* callback, void* arg) {
4195  RegTypeCache::VisitStaticRoots(callback, arg);
4196}
4197
4198void MethodVerifier::VisitRoots(RootCallback* callback, void* arg) {
4199  reg_types_.VisitRoots(callback, arg);
4200}
4201
4202}  // namespace verifier
4203}  // namespace art
4204