/*
 * Copyright (C) 2011 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_LIBDEXFILE_DEX_DEX_FILE_INL_H_
#define ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_

#include "dex_file.h"

#include "base/casts.h"
#include "base/iteration_range.h"
#include "base/leb128.h"
#include "base/stringpiece.h"
#include "base/utils.h"
#include "class_iterator.h"
#include "compact_dex_file.h"
#include "dex_instruction_iterator.h"
#include "invoke_type.h"
#include "standard_dex_file.h"

namespace art {

inline int32_t DexFile::GetStringLength(const dex::StringId& string_id) const {
  const uint8_t* ptr = DataBegin() + string_id.string_data_off_;
  return DecodeUnsignedLeb128(&ptr);
}

inline const char* DexFile::GetStringDataAndUtf16Length(const dex::StringId& string_id,
                                                        uint32_t* utf16_length) const {
  DCHECK(utf16_length != nullptr) << GetLocation();
  const uint8_t* ptr = DataBegin() + string_id.string_data_off_;
  *utf16_length = DecodeUnsignedLeb128(&ptr);
  return reinterpret_cast<const char*>(ptr);
}

inline const char* DexFile::GetStringData(const dex::StringId& string_id) const {
  uint32_t ignored;
  return GetStringDataAndUtf16Length(string_id, &ignored);
}

inline const char* DexFile::StringDataAndUtf16LengthByIdx(dex::StringIndex idx,
                                                          uint32_t* utf16_length) const {
  if (!idx.IsValid()) {
    *utf16_length = 0;
    return nullptr;
  }
  const dex::StringId& string_id = GetStringId(idx);
  return GetStringDataAndUtf16Length(string_id, utf16_length);
}

inline const char* DexFile::StringDataByIdx(dex::StringIndex idx) const {
  uint32_t unicode_length;
  return StringDataAndUtf16LengthByIdx(idx, &unicode_length);
}

inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const {
  if (!idx.IsValid()) {
    return nullptr;
  }
  const dex::TypeId& type_id = GetTypeId(idx);
  return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length);
}

inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx) const {
  if (!idx.IsValid()) {
    return nullptr;
  }
  const dex::TypeId& type_id = GetTypeId(idx);
  return StringDataByIdx(type_id.descriptor_idx_);
}

inline const char* DexFile::GetTypeDescriptor(const dex::TypeId& type_id) const {
  return StringDataByIdx(type_id.descriptor_idx_);
}

inline const char* DexFile::GetFieldTypeDescriptor(const dex::FieldId& field_id) const {
  const dex::TypeId& type_id = GetTypeId(field_id.type_idx_);
  return GetTypeDescriptor(type_id);
}

inline const char* DexFile::GetFieldName(const dex::FieldId& field_id) const {
  return StringDataByIdx(field_id.name_idx_);
}

inline const char* DexFile::GetMethodDeclaringClassDescriptor(const dex::MethodId& method_id)
    const {
  const dex::TypeId& type_id = GetTypeId(method_id.class_idx_);
  return GetTypeDescriptor(type_id);
}

inline const Signature DexFile::GetMethodSignature(const dex::MethodId& method_id) const {
  return Signature(this, GetProtoId(method_id.proto_idx_));
}

inline const Signature DexFile::GetProtoSignature(const dex::ProtoId& proto_id) const {
  return Signature(this, proto_id);
}

inline const char* DexFile::GetMethodName(const dex::MethodId& method_id) const {
  return StringDataByIdx(method_id.name_idx_);
}

inline const char* DexFile::GetMethodName(const dex::MethodId& method_id, uint32_t* utf_length)
    const {
  return StringDataAndUtf16LengthByIdx(method_id.name_idx_, utf_length);
}

inline const char* DexFile::GetMethodName(uint32_t idx, uint32_t* utf_length) const {
  return StringDataAndUtf16LengthByIdx(GetMethodId(idx).name_idx_, utf_length);
}

inline const char* DexFile::GetMethodShorty(uint32_t idx) const {
  return StringDataByIdx(GetProtoId(GetMethodId(idx).proto_idx_).shorty_idx_);
}

inline const char* DexFile::GetMethodShorty(const dex::MethodId& method_id) const {
  return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_);
}

inline const char* DexFile::GetMethodShorty(const dex::MethodId& method_id, uint32_t* length)
    const {
  // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters.
  return StringDataAndUtf16LengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length);
}

inline const char* DexFile::GetClassDescriptor(const dex::ClassDef& class_def) const {
  return StringByTypeIdx(class_def.class_idx_);
}

inline const char* DexFile::GetReturnTypeDescriptor(const dex::ProtoId& proto_id) const {
  return StringByTypeIdx(proto_id.return_type_idx_);
}

inline const char* DexFile::GetShorty(dex::ProtoIndex proto_idx) const {
  const dex::ProtoId& proto_id = GetProtoId(proto_idx);
  return StringDataByIdx(proto_id.shorty_idx_);
}

inline const dex::TryItem* DexFile::GetTryItems(const DexInstructionIterator& code_item_end,
                                                uint32_t offset) {
  return reinterpret_cast<const dex::TryItem*>
      (RoundUp(reinterpret_cast<uintptr_t>(&code_item_end.Inst()), dex::TryItem::kAlignment)) +
          offset;
}

inline bool DexFile::StringEquals(const DexFile* df1, dex::StringIndex sidx1,
                                  const DexFile* df2, dex::StringIndex sidx2) {
  uint32_t s1_len;  // Note: utf16 length != mutf8 length.
  const char* s1_data = df1->StringDataAndUtf16LengthByIdx(sidx1, &s1_len);
  uint32_t s2_len;
  const char* s2_data = df2->StringDataAndUtf16LengthByIdx(sidx2, &s2_len);
  return (s1_len == s2_len) && (strcmp(s1_data, s2_data) == 0);
}

template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream,
                                   const std::string& location,
                                   const char* declaring_class_descriptor,
                                   const std::vector<const char*>& arg_descriptors,
                                   const std::string& method_name,
                                   bool is_static,
                                   uint16_t registers_size,
                                   uint16_t ins_size,
                                   uint16_t insns_size_in_code_units,
                                   const IndexToStringData& index_to_string_data,
                                   const TypeIndexToStringData& type_index_to_string_data,
                                   const NewLocalCallback& new_local_callback) {
  if (stream == nullptr) {
    return false;
  }
  std::vector<LocalInfo> local_in_reg(registers_size);

  uint16_t arg_reg = registers_size - ins_size;
  if (!is_static) {
    const char* descriptor = declaring_class_descriptor;
    local_in_reg[arg_reg].name_ = "this";
    local_in_reg[arg_reg].descriptor_ = descriptor;
    local_in_reg[arg_reg].signature_ = nullptr;
    local_in_reg[arg_reg].start_address_ = 0;
    local_in_reg[arg_reg].reg_ = arg_reg;
    local_in_reg[arg_reg].is_live_ = true;
    arg_reg++;
  }

  DecodeUnsignedLeb128(&stream);  // Line.
  uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
  uint32_t i;
  if (parameters_size != arg_descriptors.size()) {
    LOG(ERROR) << "invalid stream - problem with parameter iterator in " << location
               << " for method " << method_name;
    return false;
  }
  for (i = 0; i < parameters_size && i < arg_descriptors.size(); ++i) {
    if (arg_reg >= registers_size) {
      LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
                 << " >= " << registers_size << ") in " << location;
      return false;
    }
    uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
    const char* descriptor = arg_descriptors[i];
    local_in_reg[arg_reg].name_ = index_to_string_data(name_idx);
    local_in_reg[arg_reg].descriptor_ = descriptor;
    local_in_reg[arg_reg].signature_ = nullptr;
    local_in_reg[arg_reg].start_address_ = 0;
    local_in_reg[arg_reg].reg_ = arg_reg;
    local_in_reg[arg_reg].is_live_ = true;
    switch (*descriptor) {
      case 'D':
      case 'J':
        arg_reg += 2;
        break;
      default:
        arg_reg += 1;
        break;
    }
  }

  uint32_t address = 0;
  for (;;)  {
    uint8_t opcode = *stream++;
    switch (opcode) {
      case DBG_END_SEQUENCE:
        // Emit all variables which are still alive at the end of the method.
        for (uint16_t reg = 0; reg < registers_size; reg++) {
          if (local_in_reg[reg].is_live_) {
            local_in_reg[reg].end_address_ = insns_size_in_code_units;
            new_local_callback(local_in_reg[reg]);
          }
        }
        return true;
      case DBG_ADVANCE_PC:
        address += DecodeUnsignedLeb128(&stream);
        break;
      case DBG_ADVANCE_LINE:
        DecodeSignedLeb128(&stream);  // Line.
        break;
      case DBG_START_LOCAL:
      case DBG_START_LOCAL_EXTENDED: {
        uint16_t reg = DecodeUnsignedLeb128(&stream);
        if (reg >= registers_size) {
          LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
                     << registers_size << ") in " << location;
          return false;
        }

        uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
        uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream);
        uint32_t signature_idx = dex::kDexNoIndex;
        if (opcode == DBG_START_LOCAL_EXTENDED) {
          signature_idx = DecodeUnsignedLeb128P1(&stream);
        }

        // Emit what was previously there, if anything
        if (local_in_reg[reg].is_live_) {
          local_in_reg[reg].end_address_ = address;
          new_local_callback(local_in_reg[reg]);
        }

        local_in_reg[reg].name_ = index_to_string_data(name_idx);
        local_in_reg[reg].descriptor_ = type_index_to_string_data(descriptor_idx);;
        local_in_reg[reg].signature_ = index_to_string_data(signature_idx);
        local_in_reg[reg].start_address_ = address;
        local_in_reg[reg].reg_ = reg;
        local_in_reg[reg].is_live_ = true;
        break;
      }
      case DBG_END_LOCAL: {
        uint16_t reg = DecodeUnsignedLeb128(&stream);
        if (reg >= registers_size) {
          LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
                     << registers_size << ") in " << location;
          return false;
        }
        // If the register is live, close it properly. Otherwise, closing an already
        // closed register is sloppy, but harmless if no further action is taken.
        if (local_in_reg[reg].is_live_) {
          local_in_reg[reg].end_address_ = address;
          new_local_callback(local_in_reg[reg]);
          local_in_reg[reg].is_live_ = false;
        }
        break;
      }
      case DBG_RESTART_LOCAL: {
        uint16_t reg = DecodeUnsignedLeb128(&stream);
        if (reg >= registers_size) {
          LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
                     << registers_size << ") in " << location;
          return false;
        }
        // If the register is live, the "restart" is superfluous,
        // and we don't want to mess with the existing start address.
        if (!local_in_reg[reg].is_live_) {
          local_in_reg[reg].start_address_ = address;
          local_in_reg[reg].is_live_ = true;
        }
        break;
      }
      case DBG_SET_PROLOGUE_END:
      case DBG_SET_EPILOGUE_BEGIN:
        break;
      case DBG_SET_FILE:
        DecodeUnsignedLeb128P1(&stream);  // name.
        break;
      default:
        address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE;
        break;
    }
  }
}

template<typename NewLocalCallback>
bool DexFile::DecodeDebugLocalInfo(uint32_t registers_size,
                                   uint32_t ins_size,
                                   uint32_t insns_size_in_code_units,
                                   uint32_t debug_info_offset,
                                   bool is_static,
                                   uint32_t method_idx,
                                   const NewLocalCallback& new_local_callback) const {
  const uint8_t* const stream = GetDebugInfoStream(debug_info_offset);
  if (stream == nullptr) {
    return false;
  }
  std::vector<const char*> arg_descriptors;
  DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
  for (; it.HasNext(); it.Next()) {
    arg_descriptors.push_back(it.GetDescriptor());
  }
  return DecodeDebugLocalInfo(stream,
                              GetLocation(),
                              GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)),
                              arg_descriptors,
                              this->PrettyMethod(method_idx),
                              is_static,
                              registers_size,
                              ins_size,
                              insns_size_in_code_units,
                              [this](uint32_t idx) {
                                return StringDataByIdx(dex::StringIndex(idx));
                              },
                              [this](uint32_t idx) {
                                return StringByTypeIdx(dex::TypeIndex(
                                    dchecked_integral_cast<uint16_t>(idx)));
                              },
                              new_local_callback);
}

template<typename DexDebugNewPosition, typename IndexToStringData>
bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream,
                                      const IndexToStringData& index_to_string_data,
                                      const DexDebugNewPosition& position_functor) {
  if (stream == nullptr) {
    return false;
  }

  PositionInfo entry;
  entry.line_ = DecodeDebugInfoParameterNames(&stream, VoidFunctor());

  for (;;)  {
    uint8_t opcode = *stream++;
    switch (opcode) {
      case DBG_END_SEQUENCE:
        return true;  // end of stream.
      case DBG_ADVANCE_PC:
        entry.address_ += DecodeUnsignedLeb128(&stream);
        break;
      case DBG_ADVANCE_LINE:
        entry.line_ += DecodeSignedLeb128(&stream);
        break;
      case DBG_START_LOCAL:
        DecodeUnsignedLeb128(&stream);  // reg.
        DecodeUnsignedLeb128P1(&stream);  // name.
        DecodeUnsignedLeb128P1(&stream);  // descriptor.
        break;
      case DBG_START_LOCAL_EXTENDED:
        DecodeUnsignedLeb128(&stream);  // reg.
        DecodeUnsignedLeb128P1(&stream);  // name.
        DecodeUnsignedLeb128P1(&stream);  // descriptor.
        DecodeUnsignedLeb128P1(&stream);  // signature.
        break;
      case DBG_END_LOCAL:
      case DBG_RESTART_LOCAL:
        DecodeUnsignedLeb128(&stream);  // reg.
        break;
      case DBG_SET_PROLOGUE_END:
        entry.prologue_end_ = true;
        break;
      case DBG_SET_EPILOGUE_BEGIN:
        entry.epilogue_begin_ = true;
        break;
      case DBG_SET_FILE: {
        uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
        entry.source_file_ = index_to_string_data(name_idx);
        break;
      }
      default: {
        int adjopcode = opcode - DBG_FIRST_SPECIAL;
        entry.address_ += adjopcode / DBG_LINE_RANGE;
        entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
        if (position_functor(entry)) {
          return true;  // early exit.
        }
        entry.prologue_end_ = false;
        entry.epilogue_begin_ = false;
        break;
      }
    }
  }
}

inline const CompactDexFile* DexFile::AsCompactDexFile() const {
  DCHECK(IsCompactDexFile());
  return down_cast<const CompactDexFile*>(this);
}

inline const StandardDexFile* DexFile::AsStandardDexFile() const {
  DCHECK(IsStandardDexFile());
  return down_cast<const StandardDexFile*>(this);
}

// Get the base of the encoded data for the given DexCode.
inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& code_item_end,
                                                   uint32_t tries_size,
                                                   uint32_t offset) {
  const uint8_t* handler_data =
      reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
  return handler_data + offset;
}

inline IterationRange<ClassIterator> DexFile::GetClasses() const {
  return { ClassIterator(*this, 0u), ClassIterator(*this, NumClassDefs()) };
}

// Returns the line number
template <typename Visitor>
inline uint32_t DexFile::DecodeDebugInfoParameterNames(const uint8_t** debug_info,
                                                       const Visitor& visitor) {
  uint32_t line = DecodeUnsignedLeb128(debug_info);
  const uint32_t parameters_size = DecodeUnsignedLeb128(debug_info);
  for (uint32_t i = 0; i < parameters_size; ++i) {
    visitor(dex::StringIndex(DecodeUnsignedLeb128P1(debug_info)));
  }
  return line;
}

}  // namespace art

#endif  // ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_
