/*
 * 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 {

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 = 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) ||
  INTRINSICS_LIST(INITIALIZE_INTRINSIC) true;
#undef INITIALIZE_INTRINSIC
  DCHECK(AreAllIntrinsicsInitialized());
}

}  // namespace art
