/*
 * Copyright (C) 2016 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_handle_impl-inl.h"

#include "class-alloc-inl.h"
#include "class_root-inl.h"

namespace art HIDDEN {
namespace mirror {

const char* MethodHandle::GetReturnTypeDescriptor(const char* invoke_method_name) {
  if (strcmp(invoke_method_name, "invoke") == 0 || strcmp(invoke_method_name, "invokeExact") == 0) {
    return "Ljava/lang/Object;";
  } else {
    return nullptr;
  }
}

void MethodHandle::Initialize(uintptr_t art_field_or_method,
                              Kind kind,
                              Handle<MethodType> method_type)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  CHECK(!Runtime::Current()->IsActiveTransaction());
  SetFieldObject<false>(CachedSpreadInvokerOffset(), nullptr);
  SetFieldObject<false>(MethodTypeOffset(), method_type.Get());
  SetFieldObject<false>(AsTypeCacheOffset(), nullptr);
  SetField32<false>(HandleKindOffset(), static_cast<uint32_t>(kind));
  SetField64<false>(ArtFieldOrMethodOffset(), art_field_or_method);
}

ObjPtr<mirror::MethodHandleImpl> MethodHandleImpl::Create(Thread* const self,
                                                          uintptr_t art_field_or_method,
                                                          MethodHandle::Kind kind,
                                                          Handle<MethodType> method_type)
    REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
  StackHandleScope<1> hs(self);
  Handle<mirror::MethodHandleImpl> mh(hs.NewHandle(ObjPtr<MethodHandleImpl>::DownCast(
      GetClassRoot<MethodHandleImpl>()->AllocObject(self))));
  mh->Initialize(art_field_or_method, kind, method_type);
  return mh.Get();
}

void MethodHandle::VisitTarget(ReflectiveValueVisitor* v) {
  void* target = GetTargetField();
  void* result;
  HeapReflectiveSourceInfo hrsi(kSourceJavaLangInvokeMethodHandle, this);
  if (GetHandleKind() < kFirstAccessorKind) {
    result = v->VisitMethod(GetTargetMethod(), hrsi);
  } else {
    result = v->VisitField(GetTargetField(), hrsi);
  }
  if (result != target) {
    SetField64<false>(ArtFieldOrMethodOffset(), reinterpret_cast<uintptr_t>(result));
  }
}


}  // namespace mirror
}  // namespace art
