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

#include "art_method-inl.h"
#include "class_linker.h"
#include "dex/invoke_type.h"
#include "intrinsics_enum.h"
#include "intrinsics_list.h"
#include "mirror/class.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"

namespace art HIDDEN {

namespace {

ArtMethod* FindIntrinsicMethod(Thread* self,
                               const char* class_name,
                               const char* method_name,
                               const char* signature)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  PointerSize image_size = class_linker->GetImagePointerSize();
  ObjPtr<mirror::Class> cls = class_linker->FindSystemClass(self, class_name);
  if (cls == nullptr) {
    LOG(FATAL) << "Could not find class of intrinsic " << class_name;
  }

  ArtMethod* method = cls->FindClassMethod(method_name, signature, image_size);
  if (method == nullptr || method->GetDeclaringClass() != cls) {
    LOG(FATAL) << "Could not find method of intrinsic "
               << class_name << " " << method_name << " " << signature;
  }
  return method;
}

// Initialize an intrinsic. Returns true if the intrinsic is already
// initialized, false otherwise.
bool InitializeIntrinsic(Thread* self,
                         Intrinsics intrinsic,
                         InvokeType invoke_type,
                         const char* class_name,
                         const char* method_name,
                         const char* signature)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  ArtMethod* method = FindIntrinsicMethod(self, class_name, method_name, signature);

  CHECK_EQ(method->GetInvokeType(), invoke_type);
  if (method->IsIntrinsic()) {
    CHECK_EQ(method->GetIntrinsic(), static_cast<uint32_t>(intrinsic));
    return true;
  } else {
    method->SetIntrinsic(static_cast<uint32_t>(intrinsic));
    return false;
  }
}

// Returns true if the intrinsic is already initialized, false otherwise.
bool IsIntrinsicInitialized(Thread* self,
                            Intrinsics intrinsic,
                            InvokeType invoke_type,
                            const char* class_name,
                            const char* method_name,
                            const char* signature)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  ArtMethod* method = FindIntrinsicMethod(self, class_name, method_name, signature);

  CHECK_EQ(method->GetInvokeType(), invoke_type);
  if (method->IsIntrinsic()) {
    CHECK_EQ(method->GetIntrinsic(), static_cast<uint32_t>(intrinsic));
    return true;
  } else {
    return false;
  }
}

bool AreAllIntrinsicsInitialized() REQUIRES_SHARED(Locks::mutator_lock_) {
  Thread* self = Thread::Current();
#define IS_INTRINSIC_INITIALIZED(Name, InvokeType, _, __, ___, ClassName, MethodName, Signature) \
  IsIntrinsicInitialized(self,                                                                   \
                         Intrinsics::k##Name,                                                    \
                         InvokeType,                                                             \
                         ClassName,                                                              \
                         MethodName,                                                             \
                         Signature) &&
  bool result = ART_INTRINSICS_LIST(IS_INTRINSIC_INITIALIZED) true;
#undef IS_INTRINSIC_INITIALIZED
  return result;
}

}  // namespace

void InitializeIntrinsics() {
  Thread* self = Thread::Current();
  // Initialization here uses the short-circuit operator || to stop
  // initializing if there's an already initialized intrinsic.
#define INITIALIZE_INTRINSIC(Name, InvokeType, _, __, ___, ClassName, MethodName, Signature) \
  InitializeIntrinsic(self,                                                                  \
                      Intrinsics::k##Name,                                                   \
                      InvokeType,                                                            \
                      ClassName,                                                             \
                      MethodName,                                                            \
                      Signature) ||
  ART_INTRINSICS_LIST(INITIALIZE_INTRINSIC) true;
#undef INITIALIZE_INTRINSIC
  DCHECK(AreAllIntrinsicsInitialized());
}

}  // namespace art
