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

namespace art {

namespace {

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

  bool VisitFrame() override REQUIRES_SHARED(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 (!IsShadowFrame() && GetCurrentOatQuickMethodHeader()->IsOptimized()) {
        CHECK(!success);
      }

      CHECK(GetVReg(m, 3, kIntVReg, &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*, [[maybe_unused]] jclass value) {
  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*, [[maybe_unused]] jclass value, 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
