/*
 * 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 "scoped_thread_state_change.h"
#include "stack.h"
#include "thread.h"

namespace art {

namespace {

class TestVisitor : public StackVisitor {
 public:
  TestVisitor(Thread* thread, Context* context)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
      : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {}

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

    if (m_name.compare("mergeOk") == 0) {
      uint32_t value = 0;

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

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

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

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

      CHECK(GetVReg(m, 4, kIntVReg, &value));
      CHECK_EQ(value, 2u);
      did_check_ = true;
    } else if (m_name.compare("mergeNotOk") == 0) {
      uint32_t value = 0;

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

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

      bool success = GetVReg(m, 2, kIntVReg, &value);
      if (m->IsOptimized(sizeof(void*))) CHECK(!success);

      CHECK(GetVReg(m, 3, kReferenceVReg, &value));
      CHECK_EQ(value, 1u);

      CHECK(GetVReg(m, 4, kFloatVReg, &value));
      uint32_t cast = bit_cast<uint32_t, float>(4.0f);
      CHECK_EQ(value, cast);
      did_check_ = true;
    } else if (m_name.compare("phiEquivalent") == 0) {
      uint32_t value = 0;

      CHECK(GetVReg(m, 0, kIntVReg, &value));
      // Quick doesn't like this one on x64.
      CHECK_EQ(value, 0u);

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

      CHECK(GetVReg(m, 2, kFloatVReg, &value));
      CHECK_EQ(value, 1u);

      did_check_ = true;
    } else if (m_name.compare("mergeReferences") == 0) {
      uint32_t value = 0;

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

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

      CHECK(GetVReg(m, 2, kReferenceVReg, &value));
      CHECK_EQ(value, 0u);

      CHECK(GetVReg(m, 3, kReferenceVReg, &value));
      CHECK_NE(value, 0u);

      did_check_ = true;
    } else if (m_name.compare("phiAllEquivalents") == 0) {
      uint32_t value = 0;

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

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

      CHECK(GetVReg(m, 2, kReferenceVReg, &value));
      CHECK_EQ(value, 0u);

      did_check_ = true;
    }

    return true;
  }

  bool did_check_ = false;
};

extern "C" JNIEXPORT void JNICALL Java_PhiLiveness_regsNativeCall(
    JNIEnv*, jclass value ATTRIBUTE_UNUSED) {
  ScopedObjectAccess soa(Thread::Current());
  std::unique_ptr<Context> context(Context::Create());
  TestVisitor visitor(soa.Self(), context.get());
  visitor.WalkStack();
  CHECK(visitor.did_check_);
}

extern "C" JNIEXPORT void JNICALL Java_PhiLiveness_regsNativeCallWithParameters(
    JNIEnv*, jclass value ATTRIBUTE_UNUSED, jobject main, jint int_value, jfloat float_value) {
  ScopedObjectAccess soa(Thread::Current());
  std::unique_ptr<Context> context(Context::Create());
  CHECK(soa.Decode<mirror::Object*>(main) == nullptr);
  CHECK_EQ(int_value, 0);
  int32_t cast = bit_cast<int32_t, float>(float_value);
  CHECK_EQ(cast, 0);
  TestVisitor visitor(soa.Self(), context.get());
  visitor.WalkStack();
  CHECK(visitor.did_check_);
}

}  // namespace

}  // namespace art
