/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_INL_H_
#define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_INL_H_

#include "base/logging.h"
#include "method_verifier.h"
#include "mirror/class_loader.h"
#include "mirror/dex_cache.h"
#include "handle_scope-inl.h"

namespace art {
namespace verifier {

inline const DexFile::CodeItem* MethodVerifier::CodeItem() const {
  return code_item_;
}

inline RegisterLine* MethodVerifier::GetRegLine(uint32_t dex_pc) {
  return reg_table_.GetLine(dex_pc);
}

inline const InstructionFlags& MethodVerifier::GetInstructionFlags(size_t index) const {
  return insn_flags_[index];
}

inline InstructionFlags& MethodVerifier::GetInstructionFlags(size_t index) {
  return insn_flags_[index];
}

inline mirror::ClassLoader* MethodVerifier::GetClassLoader() {
  return class_loader_.Get();
}

inline mirror::DexCache* MethodVerifier::GetDexCache() {
  return dex_cache_.Get();
}

inline ArtMethod* MethodVerifier::GetMethod() const {
  return mirror_method_;
}

inline MethodReference MethodVerifier::GetMethodReference() const {
  return MethodReference(dex_file_, dex_method_idx_);
}

inline uint32_t MethodVerifier::GetAccessFlags() const {
  return method_access_flags_;
}

inline bool MethodVerifier::HasCheckCasts() const {
  return has_check_casts_;
}

inline bool MethodVerifier::HasVirtualOrInterfaceInvokes() const {
  return has_virtual_or_interface_invokes_;
}

inline bool MethodVerifier::HasFailures() const {
  return !failure_messages_.empty();
}

inline const RegType& MethodVerifier::ResolveCheckedClass(uint32_t class_idx) {
  DCHECK(!HasFailures());
  const RegType& result = ResolveClassAndCheckAccess(class_idx);
  DCHECK(!HasFailures());
  return result;
}

}  // namespace verifier
}  // namespace art

#endif  // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_INL_H_
