// Copyright 2011 Google Inc. All Rights Reserved.

#include <stdio.h>

#include "UniquePtr.h"
#include "class_linker.h"
#include "common_test.h"
#include "dex_verifier.h"
// #include "heap.h"
#include "object.h"
#include "jni.h"

namespace art {

#define REG(method, reg_vector, reg) \
  ( ((reg) < (method)->NumRegisters()) &&                       \
    (( *((reg_vector) + (reg)/8) >> ((reg) % 8) ) & 0x01) )

#define EXPECT_REGS(...) do {          \
    int t[] = {__VA_ARGS__};             \
    int t_size = sizeof(t) / sizeof(*t);      \
    for (int i = 0; i < t_size; ++i)          \
      EXPECT_TRUE(REG(m, reg_vector, t[i]));  \
  } while(false)

static int gJava_StackWalk_refmap_calls = 0;

struct ReferenceMapVisitor : public Thread::StackVisitor {
  ReferenceMapVisitor() {
  }

  void VisitFrame(const Frame& frame, uintptr_t pc) {
    Method* m = frame.GetMethod();
    if (!m ||m->IsNative()) {
      return;
    }
    LOG(INFO) << "At " << PrettyMethod(m, false);

    art::DexVerifier::RegisterMap* map = new art::DexVerifier::RegisterMap(
        m->GetRegisterMapHeader(),
        m->GetRegisterMapData());

    if (!pc) {
      // pc == NULL: m is either a native method or a phony method
      return;
    }
    if (m->IsPhony()) {
      LOG(WARNING) << "no PC for " << PrettyMethod(m);
      return;
    }

    const uint8_t* reg_vector = art::DexVerifier::RegisterMapGetLine(map, m->ToDexPC(pc));
    std::string m_name = m->GetName()->ToModifiedUtf8();

    // Given the method name and the number of times the method has been called,
    // we know the Dex registers with live reference values. Assert that what we
    // find is what is expected.
    if (m_name.compare("f") == 0) {
      if (gJava_StackWalk_refmap_calls == 1) {
        EXPECT_EQ(0U, m->ToDexPC(pc));
        EXPECT_REGS(1);
      } else {
        CHECK(gJava_StackWalk_refmap_calls == 2);
        EXPECT_EQ(4U, m->ToDexPC(pc));
        EXPECT_REGS(1);  // Note that v1 is not in the minimal root set
      }
    } else if (m_name.compare("g") == 0) {
      if (gJava_StackWalk_refmap_calls == 1) {
        EXPECT_EQ(0xaU, m->ToDexPC(pc));
        EXPECT_REGS(1, 2, 3);
      } else {
        CHECK(gJava_StackWalk_refmap_calls == 2);
        EXPECT_EQ(0xaU, m->ToDexPC(pc));
          EXPECT_REGS(1, 2, 3);
      }
    } else if (m_name.compare("shlemiel") == 0) {
      if (gJava_StackWalk_refmap_calls == 1) {
        EXPECT_EQ(0x2d5U, m->ToDexPC(pc));
        EXPECT_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
      } else {
        CHECK(gJava_StackWalk_refmap_calls == 2);
        EXPECT_EQ(0x2d5U, m->ToDexPC(pc));
        EXPECT_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
      }
    }

    LOG(INFO) << reg_vector;
  }
};

extern "C"
JNIEXPORT jint JNICALL Java_StackWalk_refmap(JNIEnv* env, jobject thisObj, jint count) {
  EXPECT_EQ(count, 0);
  gJava_StackWalk_refmap_calls++;

  // Visitor
  ReferenceMapVisitor mapper;
  Thread::Current()->WalkStack(&mapper);

  return count + 1;
}

extern "C"
JNIEXPORT jint JNICALL Java_StackWalk_refmap2(JNIEnv* env, jobject thisObj, jint count) {
  gJava_StackWalk_refmap_calls++;

  // Visitor
  ReferenceMapVisitor mapper;
  Thread::Current()->WalkStack(&mapper);

  return count + 1;
}

}
