/*
 * 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.
 */

#include <memory>

#include "class_linker.h"
#include "common_runtime_test.h"
#include "dex_file.h"
#include "dex_file-inl.h"
#include "gtest/gtest.h"
#include "leb128.h"
#include "mirror/class-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/object-inl.h"
#include "mirror/stack_trace_element.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "handle_scope-inl.h"
#include "thread.h"
#include "vmap_table.h"

namespace art {

class ExceptionTest : public CommonRuntimeTest {
 protected:
  virtual void SetUp() {
    CommonRuntimeTest::SetUp();

    ScopedObjectAccess soa(Thread::Current());
    StackHandleScope<2> hs(soa.Self());
    Handle<mirror::ClassLoader> class_loader(
        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("ExceptionHandle"))));
    my_klass_ = class_linker_->FindClass(soa.Self(), "LExceptionHandle;", class_loader);
    ASSERT_TRUE(my_klass_ != nullptr);
    Handle<mirror::Class> klass(hs.NewHandle(my_klass_));
    class_linker_->EnsureInitialized(soa.Self(), klass, true, true);
    my_klass_ = klass.Get();

    dex_ = my_klass_->GetDexCache()->GetDexFile();

    uint32_t code_size = 12;
    for (size_t i = 0 ; i < code_size; i++) {
      fake_code_.push_back(0x70 | i);
    }

    fake_mapping_data_.PushBackUnsigned(4);  // first element is count
    fake_mapping_data_.PushBackUnsigned(4);  // total (non-length) elements
    fake_mapping_data_.PushBackUnsigned(2);  // count of pc to dex elements
                                      // ---  pc to dex table
    fake_mapping_data_.PushBackUnsigned(3 - 0);  // offset 3
    fake_mapping_data_.PushBackSigned(3 - 0);    // maps to dex offset 3
                                      // ---  dex to pc table
    fake_mapping_data_.PushBackUnsigned(3 - 0);  // offset 3
    fake_mapping_data_.PushBackSigned(3 - 0);    // maps to dex offset 3

    fake_vmap_table_data_.PushBackUnsigned(0 + VmapTable::kEntryAdjustment);

    fake_gc_map_.push_back(0);  // 0 bytes to encode references and native pc offsets.
    fake_gc_map_.push_back(0);
    fake_gc_map_.push_back(0);  // 0 entries.
    fake_gc_map_.push_back(0);

    const std::vector<uint8_t>& fake_vmap_table_data = fake_vmap_table_data_.GetData();
    const std::vector<uint8_t>& fake_mapping_data = fake_mapping_data_.GetData();
    uint32_t vmap_table_offset = sizeof(OatQuickMethodHeader) + fake_vmap_table_data.size();
    uint32_t mapping_table_offset = vmap_table_offset + fake_mapping_data.size();
    uint32_t gc_map_offset = mapping_table_offset + fake_gc_map_.size();
    OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, gc_map_offset,
                                       4 * sizeof(void*), 0u, 0u, code_size);
    fake_header_code_and_maps_.resize(sizeof(method_header));
    memcpy(&fake_header_code_and_maps_[0], &method_header, sizeof(method_header));
    fake_header_code_and_maps_.insert(fake_header_code_and_maps_.begin(),
                                      fake_vmap_table_data.begin(), fake_vmap_table_data.end());
    fake_header_code_and_maps_.insert(fake_header_code_and_maps_.begin(),
                                      fake_mapping_data.begin(), fake_mapping_data.end());
    fake_header_code_and_maps_.insert(fake_header_code_and_maps_.begin(),
                                      fake_gc_map_.begin(), fake_gc_map_.end());
    fake_header_code_and_maps_.insert(fake_header_code_and_maps_.end(),
                                      fake_code_.begin(), fake_code_.end());

    // NOTE: Don't align the code (it will not be executed) but check that the Thumb2
    // adjustment will be a NOP, see ArtMethod::EntryPointToCodePointer().
    CHECK_EQ(mapping_table_offset & 1u, 0u);
    const uint8_t* code_ptr = &fake_header_code_and_maps_[gc_map_offset];

    method_f_ = my_klass_->FindVirtualMethod("f", "()I");
    ASSERT_TRUE(method_f_ != nullptr);
    method_f_->SetEntryPointFromQuickCompiledCode(code_ptr);

    method_g_ = my_klass_->FindVirtualMethod("g", "(I)V");
    ASSERT_TRUE(method_g_ != nullptr);
    method_g_->SetEntryPointFromQuickCompiledCode(code_ptr);
  }

  const DexFile* dex_;

  std::vector<uint8_t> fake_code_;
  Leb128EncodingVector fake_mapping_data_;
  Leb128EncodingVector fake_vmap_table_data_;
  std::vector<uint8_t> fake_gc_map_;
  std::vector<uint8_t> fake_header_code_and_maps_;

  mirror::ArtMethod* method_f_;
  mirror::ArtMethod* method_g_;

 private:
  mirror::Class* my_klass_;
};

TEST_F(ExceptionTest, FindCatchHandler) {
  ScopedObjectAccess soa(Thread::Current());
  const DexFile::CodeItem* code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());

  ASSERT_TRUE(code_item != nullptr);

  ASSERT_EQ(2u, code_item->tries_size_);
  ASSERT_NE(0u, code_item->insns_size_in_code_units_);

  const DexFile::TryItem *t0, *t1;
  t0 = dex_->GetTryItems(*code_item, 0);
  t1 = dex_->GetTryItems(*code_item, 1);
  EXPECT_LE(t0->start_addr_, t1->start_addr_);
  {
    CatchHandlerIterator iter(*code_item, 4 /* Dex PC in the first try block */);
    EXPECT_STREQ("Ljava/io/IOException;", dex_->StringByTypeIdx(iter.GetHandlerTypeIndex()));
    ASSERT_TRUE(iter.HasNext());
    iter.Next();
    EXPECT_STREQ("Ljava/lang/Exception;", dex_->StringByTypeIdx(iter.GetHandlerTypeIndex()));
    ASSERT_TRUE(iter.HasNext());
    iter.Next();
    EXPECT_FALSE(iter.HasNext());
  }
  {
    CatchHandlerIterator iter(*code_item, 8 /* Dex PC in the second try block */);
    EXPECT_STREQ("Ljava/io/IOException;", dex_->StringByTypeIdx(iter.GetHandlerTypeIndex()));
    ASSERT_TRUE(iter.HasNext());
    iter.Next();
    EXPECT_FALSE(iter.HasNext());
  }
  {
    CatchHandlerIterator iter(*code_item, 11 /* Dex PC not in any try block */);
    EXPECT_FALSE(iter.HasNext());
  }
}

TEST_F(ExceptionTest, StackTraceElement) {
  Thread* thread = Thread::Current();
  thread->TransitionFromSuspendedToRunnable();
  bool started = runtime_->Start();
  CHECK(started);
  JNIEnv* env = thread->GetJniEnv();
  ScopedObjectAccess soa(env);

  std::vector<uintptr_t> fake_stack;
  Runtime* r = Runtime::Current();
  r->SetInstructionSet(kRuntimeISA);
  mirror::ArtMethod* save_method = r->CreateCalleeSaveMethod();
  r->SetCalleeSaveMethod(save_method, Runtime::kSaveAll);
  QuickMethodFrameInfo frame_info = save_method->GetQuickFrameInfo();

  ASSERT_EQ(kStackAlignment, 16U);
  // ASSERT_EQ(sizeof(uintptr_t), sizeof(uint32_t));


  // Create three fake stack frames with mapping data created in SetUp. We map offset 3 in the
  // code to dex pc 3.
  const uint32_t dex_pc = 3;

  // Create the stack frame for the callee save method, expected by the runtime.
  fake_stack.push_back(reinterpret_cast<uintptr_t>(save_method));
  for (size_t i = 0; i < frame_info.FrameSizeInBytes() - 2 * sizeof(uintptr_t);
       i += sizeof(uintptr_t)) {
    fake_stack.push_back(0);
  }

  fake_stack.push_back(method_g_->ToNativeQuickPc(dex_pc));  // return pc

  // Create/push fake 16byte stack frame for method g
  fake_stack.push_back(reinterpret_cast<uintptr_t>(method_g_));
  fake_stack.push_back(0);
  fake_stack.push_back(0);
  fake_stack.push_back(method_f_->ToNativeQuickPc(dex_pc));  // return pc

  // Create/push fake 16byte stack frame for method f
  fake_stack.push_back(reinterpret_cast<uintptr_t>(method_f_));
  fake_stack.push_back(0);
  fake_stack.push_back(0);
  fake_stack.push_back(0xEBAD6070);  // return pc

  // Push Method* of NULL to terminate the trace
  fake_stack.push_back(0);

  // Push null values which will become null incoming arguments.
  fake_stack.push_back(0);
  fake_stack.push_back(0);
  fake_stack.push_back(0);

  // Set up thread to appear as if we called out of method_g_ at pc dex 3
  thread->SetTopOfStack(reinterpret_cast<StackReference<mirror::ArtMethod>*>(&fake_stack[0]));

  jobject internal = thread->CreateInternalStackTrace<false>(soa);
  ASSERT_TRUE(internal != nullptr);
  jobjectArray ste_array = Thread::InternalStackTraceToStackTraceElementArray(soa, internal);
  ASSERT_TRUE(ste_array != nullptr);
  mirror::ObjectArray<mirror::StackTraceElement>* trace_array =
      soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(ste_array);

  ASSERT_TRUE(trace_array != nullptr);
  ASSERT_TRUE(trace_array->Get(0) != nullptr);
  EXPECT_STREQ("ExceptionHandle",
               trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
  EXPECT_STREQ("ExceptionHandle.java",
               trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
  EXPECT_STREQ("g", trace_array->Get(0)->GetMethodName()->ToModifiedUtf8().c_str());
  EXPECT_EQ(37, trace_array->Get(0)->GetLineNumber());

  ASSERT_TRUE(trace_array->Get(1) != nullptr);
  EXPECT_STREQ("ExceptionHandle",
               trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
  EXPECT_STREQ("ExceptionHandle.java",
               trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
  EXPECT_STREQ("f", trace_array->Get(1)->GetMethodName()->ToModifiedUtf8().c_str());
  EXPECT_EQ(22, trace_array->Get(1)->GetLineNumber());

  thread->SetTopOfStack(nullptr);  // Disarm the assertion that no code is running when we detach.
}

}  // namespace art
