/*
 * Copyright (C) 2018 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 "method_handles.h"

#include "class_linker-inl.h"
#include "class_root.h"
#include "common_runtime_test.h"
#include "handle_scope-inl.h"
#include "jvalue-inl.h"
#include "mirror/method_type.h"
#include "mirror/object_array-alloc-inl.h"
#include "mirror/object_array-inl.h"
#include "reflection.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"

namespace art {

namespace {
  bool IsClassCastException(ObjPtr<mirror::Throwable> throwable)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    return throwable->GetClass()->DescriptorEquals("Ljava/lang/ClassCastException;");
  }

  bool IsNullPointerException(ObjPtr<mirror::Throwable> throwable)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    return throwable->GetClass()->DescriptorEquals("Ljava/lang/NullPointerException;");
  }

  bool IsWrongMethodTypeException(ObjPtr<mirror::Throwable> throwable)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    return throwable->GetClass()->DescriptorEquals("Ljava/lang/invoke/WrongMethodTypeException;");
  }

  static ObjPtr<mirror::MethodType> CreateVoidMethodType(Thread* self,
                                                         Handle<mirror::Class> parameter_type)
        REQUIRES_SHARED(Locks::mutator_lock_) {
    ClassLinker* cl = Runtime::Current()->GetClassLinker();
    StackHandleScope<2> hs(self);
    ObjPtr<mirror::Class> class_array_type = GetClassRoot<mirror::ObjectArray<mirror::Class>>(cl);
    auto parameter_types = hs.NewHandle(
        mirror::ObjectArray<mirror::Class>::Alloc(self, class_array_type, 1));
    parameter_types->Set(0, parameter_type.Get());
    Handle<mirror::Class> void_class = hs.NewHandle(GetClassRoot(ClassRoot::kPrimitiveVoid, cl));
    return mirror::MethodType::Create(self, void_class, parameter_types);
  }

  static bool TryConversion(Thread* self,
                            Handle<mirror::Class> from,
                            Handle<mirror::Class> to,
                            JValue* value)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    StackHandleScope<2> hs(self);
    Handle<mirror::MethodType> from_mt = hs.NewHandle(CreateVoidMethodType(self, from));
    Handle<mirror::MethodType> to_mt = hs.NewHandle(CreateVoidMethodType(self, to));
    return ConvertJValueCommon(from_mt, to_mt, from.Get(), to.Get(), value);
  }
}  // namespace

class MethodHandlesTest : public CommonRuntimeTest {};

//
// Primitive -> Primitive Conversions
//

TEST_F(MethodHandlesTest, SupportedPrimitiveWideningBI) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('B'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('I'));
  JValue value = JValue::FromPrimitive(static_cast<int8_t>(3));
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_EQ(3, value.GetI());
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
}

TEST_F(MethodHandlesTest, SupportedPrimitiveWideningCJ) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('C'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('J'));
  uint16_t raw_value = 0x8000;
  JValue value = JValue::FromPrimitive(raw_value);
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  ASSERT_EQ(static_cast<int64_t>(raw_value), value.GetJ());
}

TEST_F(MethodHandlesTest, SupportedPrimitiveWideningIF) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('I'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('F'));
  JValue value = JValue::FromPrimitive(-16);
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  ASSERT_FLOAT_EQ(-16.0f, value.GetF());
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveWideningBC) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('B'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('C'));
  JValue value;
  value.SetB(0);
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveWideningSC) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('S'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('C'));
  JValue value;
  value.SetS(0x1234);
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveWideningDJ) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('D'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('J'));
  JValue value;
  value.SetD(1e72);
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveWideningZI) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('Z'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('I'));
  JValue value;
  value.SetZ(true);
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

//
// Reference -> Reference Conversions
//

TEST_F(MethodHandlesTest, SupportedReferenceCast) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  static const int32_t kInitialValue = 101;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Object> boxed_value = hs.NewHandle(BoxPrimitive(Primitive::kPrimInt, value));
  Handle<mirror::Class> from = hs.NewHandle(boxed_value->GetClass());
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Number;"));
  value.SetL(boxed_value.Get());
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  JValue unboxed_value;
  ASSERT_TRUE(UnboxPrimitiveForResult(value.GetL(), cl->FindPrimitiveClass('I'), &unboxed_value));
  ASSERT_EQ(kInitialValue, unboxed_value.GetI());
}

TEST_F(MethodHandlesTest, UnsupportedReferenceCast) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  JValue value = JValue::FromPrimitive(3.733e2);
  Handle<mirror::Object> boxed_value = hs.NewHandle(BoxPrimitive(Primitive::kPrimDouble, value));
  Handle<mirror::Class> from = hs.NewHandle(boxed_value->GetClass());
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Integer;"));
  value.SetL(boxed_value.Get());
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsClassCastException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

//
// Primitive -> Reference Conversions
//

TEST_F(MethodHandlesTest, SupportedPrimitiveConversionPrimitiveToBoxed) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  const int32_t kInitialValue = 1;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('I'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Integer;"));
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  JValue unboxed_to_value;
  ASSERT_TRUE(UnboxPrimitiveForResult(value.GetL(), from.Get(), &unboxed_to_value));
  ASSERT_EQ(kInitialValue, unboxed_to_value.GetI());
}

TEST_F(MethodHandlesTest, SupportedPrimitiveConversionPrimitiveToBoxedSuper) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  const int32_t kInitialValue = 1;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('I'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Number;"));
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  JValue unboxed_to_value;
  ASSERT_TRUE(UnboxPrimitiveForResult(value.GetL(), from.Get(), &unboxed_to_value));
  ASSERT_EQ(kInitialValue, unboxed_to_value.GetI());
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveConversionNotBoxable) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  const int32_t kInitialValue = 1;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('I'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Runtime;"));
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveConversionPrimitiveToBoxedWider) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  const int32_t kInitialValue = 1;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('I'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Long;"));
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedPrimitiveConversionPrimitiveToBoxedNarrower) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  const int32_t kInitialValue = 1;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Class> from = hs.NewHandle(cl->FindPrimitiveClass('I'));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Byte;"));
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

//
// Reference -> Primitive Conversions
//

TEST_F(MethodHandlesTest, SupportedBoxedToPrimitiveConversion) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  const int32_t kInitialValue = 101;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Object> boxed_value = hs.NewHandle(BoxPrimitive(Primitive::kPrimInt, value));
  Handle<mirror::Class> from = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Integer;"));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('I'));
  value.SetL(boxed_value.Get());
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_FALSE(soa.Self()->IsExceptionPending());
  ASSERT_EQ(kInitialValue, value.GetI());
}

TEST_F(MethodHandlesTest, SupportedBoxedToWiderPrimitiveConversion) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  static const int32_t kInitialValue = 101;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Object> boxed_value = hs.NewHandle(BoxPrimitive(Primitive::kPrimInt, value));
  Handle<mirror::Class> from = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Integer;"));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('J'));
  value.SetL(boxed_value.Get());
  ASSERT_TRUE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_EQ(kInitialValue, value.GetJ());
}

TEST_F(MethodHandlesTest, UnsupportedNullBoxedToPrimitiveConversion) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  JValue value = JValue::FromPrimitive(101);
  ScopedNullHandle<mirror::Object> boxed_value;
  Handle<mirror::Class> from = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Integer;"));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('I'));
  value.SetL(boxed_value.Get());
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsNullPointerException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedNotBoxReferenceToPrimitiveConversion) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> from = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Class;"));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('I'));
  // Set value to be converted as some non-primitive type.
  JValue value;
  value.SetL(cl->FindPrimitiveClass('V'));
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedBoxedToNarrowerPrimitiveConversionNoCast) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  static const int32_t kInitialValue = 101;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Object> boxed_value = hs.NewHandle(BoxPrimitive(Primitive::kPrimInt, value));
  Handle<mirror::Class> from = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Integer;"));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('S'));
  value.SetL(boxed_value.Get());
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

TEST_F(MethodHandlesTest, UnsupportedBoxedToNarrowerPrimitiveConversionWithCast) {
  ScopedObjectAccess soa(Thread::Current());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();
  StackHandleScope<3> hs(soa.Self());
  static const double kInitialValue = 1e77;
  JValue value = JValue::FromPrimitive(kInitialValue);
  Handle<mirror::Object> boxed_value = hs.NewHandle(BoxPrimitive(Primitive::kPrimDouble, value));
  Handle<mirror::Class> from = hs.NewHandle(cl->FindSystemClass(soa.Self(), "Ljava/lang/Number;"));
  Handle<mirror::Class> to = hs.NewHandle(cl->FindPrimitiveClass('F'));
  value.SetL(boxed_value.Get());
  ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value));
  ASSERT_TRUE(soa.Self()->IsExceptionPending());
  ASSERT_TRUE(IsClassCastException(soa.Self()->GetException()));
  soa.Self()->ClearException();
}

}  // namespace art
