/*
 * Copyright (C) 2015 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 "arch/context.h"
#include "art_method-inl.h"
#include "jni.h"
#include "oat_quick_method_header.h"
#include "scoped_thread_state_change.h"
#include "stack.h"
#include "thread.h"

namespace art {

namespace {

class TestVisitor : public StackVisitor {
 public:
  TestVisitor(Thread* thread, Context* context, mirror::Object* this_value)
      SHARED_REQUIRES(Locks::mutator_lock_)
      : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
        this_value_(this_value),
        found_method_index_(0) {}

  bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
    ArtMethod* m = GetMethod();
    std::string m_name(m->GetName());

    if (m_name.compare("testSimpleVReg") == 0) {
      found_method_index_ = 1;
      uint32_t value = 0;

      CHECK(GetVReg(m, 0, kIntVReg, &value));
      CHECK_EQ(value, 42u);

      bool success = GetVReg(m, 1, kIntVReg, &value);
      if (!IsCurrentFrameInInterpreter() && GetCurrentOatQuickMethodHeader()->IsOptimized()) {
        CHECK(!success);
      }

      success = GetVReg(m, 2, kIntVReg, &value);
      if (!IsCurrentFrameInInterpreter() && GetCurrentOatQuickMethodHeader()->IsOptimized()) {
        CHECK(!success);
      }

      CHECK(GetVReg(m, 3, kReferenceVReg, &value));
      CHECK_EQ(reinterpret_cast<mirror::Object*>(value), this_value_);

      CHECK(GetVReg(m, 4, kIntVReg, &value));
      CHECK_EQ(value, 1u);

      CHECK(GetVReg(m, 5, kFloatVReg, &value));
      uint32_t cast = bit_cast<uint32_t, float>(1.0f);
      CHECK_EQ(value, cast);

      CHECK(GetVReg(m, 6, kIntVReg, &value));
      CHECK_EQ(value, 2u);

      CHECK(GetVReg(m, 7, kIntVReg, &value));
      CHECK_EQ(value, true);

      CHECK(GetVReg(m, 8, kIntVReg, &value));
      CHECK_EQ(value, 3u);

      CHECK(GetVReg(m, 9, kIntVReg, &value));
      CHECK_EQ(value, static_cast<uint32_t>('c'));
    } else if (m_name.compare("testPairVReg") == 0) {
      found_method_index_ = 2;
      uint64_t value = 0;
      CHECK(GetVRegPair(m, 0, kLongLoVReg, kLongHiVReg, &value));
      CHECK_EQ(value, 42u);

      bool success = GetVRegPair(m, 2, kLongLoVReg, kLongHiVReg, &value);
      if (!IsCurrentFrameInInterpreter() && GetCurrentOatQuickMethodHeader()->IsOptimized()) {
        CHECK(!success);
      }

      success = GetVRegPair(m, 4, kLongLoVReg, kLongHiVReg, &value);
      if (!IsCurrentFrameInInterpreter() && GetCurrentOatQuickMethodHeader()->IsOptimized()) {
        CHECK(!success);
      }

      uint32_t value32 = 0;
      CHECK(GetVReg(m, 6, kReferenceVReg, &value32));
      CHECK_EQ(reinterpret_cast<mirror::Object*>(value32), this_value_);

      CHECK(GetVRegPair(m, 7, kLongLoVReg, kLongHiVReg, &value));
      CHECK_EQ(static_cast<int64_t>(value), std::numeric_limits<int64_t>::min());

      CHECK(GetVRegPair(m, 9, kLongLoVReg, kLongHiVReg, &value));
      CHECK_EQ(static_cast<int64_t>(value), std::numeric_limits<int64_t>::max());

      CHECK(GetVRegPair(m, 11, kLongLoVReg, kLongHiVReg, &value));
      CHECK_EQ(value, 0u);

      CHECK(GetVRegPair(m, 13, kDoubleLoVReg, kDoubleHiVReg, &value));
      uint64_t cast = bit_cast<uint64_t, double>(2.0);
      CHECK_EQ(value, cast);
    }

    return true;
  }

  mirror::Object* this_value_;

  // Value returned to Java to ensure the methods testSimpleVReg and testPairVReg
  // have been found and tested.
  jint found_method_index_;
};

extern "C" JNIEXPORT jint JNICALL Java_Main_doNativeCall(JNIEnv*, jobject value) {
  ScopedObjectAccess soa(Thread::Current());
  std::unique_ptr<Context> context(Context::Create());
  TestVisitor visitor(soa.Self(), context.get(), soa.Decode<mirror::Object*>(value));
  visitor.WalkStack();
  return visitor.found_method_index_;
}

}  // namespace

}  // namespace art
