/*
 * Copyright (C) 2012 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 <stdint.h>

#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/callee_save_type.h"
#include "callee_save_frame.h"
#include "dex/dex_file-inl.h"
#include "entrypoints/entrypoint_utils-inl.h"
#include "gc_root-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object_reference.h"

namespace art {

// Helper function to do a null check after trying to resolve the field. Not for statics since obj
// does not exist there. There is a suspend check, object is a double pointer to update the value
// in the caller in case it moves.
template<FindFieldType type, bool kAccessCheck>
ALWAYS_INLINE static inline ArtField* FindInstanceField(uint32_t field_idx,
                                                        ArtMethod* referrer,
                                                        Thread* self,
                                                        size_t size,
                                                        mirror::Object** obj)
    REQUIRES(!Roles::uninterruptible_)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  StackHandleScope<1> hs(self);
  HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj));
  ArtField* field = FindFieldFromCode<type, kAccessCheck>(field_idx, referrer, self, size);
  if (LIKELY(field != nullptr) && UNLIKELY(h == nullptr)) {
    ThrowNullPointerExceptionForFieldAccess(field, (type & FindFieldFlags::ReadBit) != 0);
    return nullptr;
  }
  return field;
}

static ArtMethod* GetReferrer(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
  if (kIsDebugBuild) {
    // stub_test doesn't call this code with a proper frame, so get the outer, and if
    // it does not have compiled code return it.
    ArtMethod* outer = GetCalleeSaveOuterMethod(self, CalleeSaveType::kSaveRefsOnly);
    if (outer->GetEntryPointFromQuickCompiledCode() == nullptr) {
      return outer;
    }
  }
  return GetCalleeSaveMethodCallerAndOuterMethod(self, CalleeSaveType::kSaveRefsOnly).caller;
}

// Macro used to define this set of functions:
//
//   art{Get,Set}<Kind>{Static,Instance}FromCode
//   art{Get,Set}<Kind>{Static,Instance}FromCompiledCode
//
#define ART_GET_FIELD_FROM_CODE(Kind, PrimitiveType, RetType, SetType,         \
                                PrimitiveOrObject, IsObject, Ptr)              \
  extern "C" RetType artGet ## Kind ## StaticFromCode(uint32_t field_idx,      \
                                                      ArtMethod* referrer,     \
                                                      Thread* self)            \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    ScopedQuickEntrypointChecks sqec(self);                                    \
    ArtField* field = FindFieldFast(                                           \
        field_idx, referrer, Static ## PrimitiveOrObject ## Read,              \
        sizeof(PrimitiveType));                                                \
    if (LIKELY(field != nullptr)) {                                            \
      return field->Get ## Kind (field->GetDeclaringClass())Ptr;  /* NOLINT */ \
    }                                                                          \
    field = FindFieldFromCode<Static ## PrimitiveOrObject ## Read, true>(      \
        field_idx, referrer, self, sizeof(PrimitiveType));                     \
    if (LIKELY(field != nullptr)) {                                            \
      return field->Get ## Kind (field->GetDeclaringClass())Ptr;  /* NOLINT */ \
    }                                                                          \
    /* Will throw exception by checking with Thread::Current. */               \
    return 0;                                                                  \
  }                                                                            \
                                                                               \
  extern "C" RetType artGet ## Kind ## InstanceFromCode(uint32_t field_idx,    \
                                                        mirror::Object* obj,   \
                                                        ArtMethod* referrer,   \
                                                        Thread* self)          \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    ScopedQuickEntrypointChecks sqec(self);                                    \
    ArtField* field = FindFieldFast(                                           \
        field_idx, referrer, Instance ## PrimitiveOrObject ## Read,            \
        sizeof(PrimitiveType));                                                \
    if (LIKELY(field != nullptr) && obj != nullptr) {                          \
      return field->Get ## Kind (obj)Ptr;  /* NOLINT */                        \
    }                                                                          \
    field = FindInstanceField<Instance ## PrimitiveOrObject ## Read, true>(    \
        field_idx, referrer, self, sizeof(PrimitiveType), &obj);               \
    if (LIKELY(field != nullptr)) {                                            \
      return field->Get ## Kind (obj)Ptr;  /* NOLINT */                        \
    }                                                                          \
    /* Will throw exception by checking with Thread::Current. */               \
    return 0;                                                                  \
  }                                                                            \
                                                                               \
  extern "C" int artSet ## Kind ## StaticFromCode(uint32_t field_idx,          \
                                                  SetType new_value,           \
                                                  ArtMethod* referrer,         \
                                                  Thread* self)                \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    ScopedQuickEntrypointChecks sqec(self);                                    \
    ArtField* field = FindFieldFast(                                           \
        field_idx, referrer, Static ## PrimitiveOrObject ## Write,             \
        sizeof(PrimitiveType));                                                \
    if (UNLIKELY(field == nullptr)) {                                          \
      if (IsObject) {                                                          \
        StackHandleScope<1> hs(self);                                          \
        HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(               \
            reinterpret_cast<mirror::Object**>(&new_value)));                  \
        field = FindFieldFromCode<Static ## PrimitiveOrObject ## Write, true>( \
            field_idx, referrer, self, sizeof(PrimitiveType));                 \
      } else {                                                                 \
        field = FindFieldFromCode<Static ## PrimitiveOrObject ## Write, true>( \
            field_idx, referrer, self, sizeof(PrimitiveType));                 \
      }                                                                        \
      if (UNLIKELY(field == nullptr)) {                                        \
        return -1;                                                             \
      }                                                                        \
    }                                                                          \
    if (!referrer->SkipAccessChecks() && IsObject && new_value != 0) {         \
      StackArtFieldHandleScope<1> rhs(self);                                   \
      ReflectiveHandle<ArtField> field_handle(rhs.NewHandle(field));           \
      if (field->ResolveType().IsNull()) {                                     \
        self->AssertPendingException();                                        \
        return -1;                                                             \
      }                                                                        \
      field = field_handle.Get();                                              \
    }                                                                          \
    field->Set ## Kind <false>(field->GetDeclaringClass(), new_value);         \
    return 0;                                                                  \
  }                                                                            \
                                                                               \
  extern "C" int artSet ## Kind ## InstanceFromCode(uint32_t field_idx,        \
                                                    mirror::Object* obj,       \
                                                    SetType new_value,         \
                                                    ArtMethod* referrer,       \
                                                    Thread* self)              \
    REQUIRES_SHARED(Locks::mutator_lock_) {                                    \
    ScopedQuickEntrypointChecks sqec(self);                                    \
    ArtField* field = FindFieldFast(                                           \
        field_idx, referrer, Instance ## PrimitiveOrObject ## Write,           \
        sizeof(PrimitiveType));                                                \
    if (UNLIKELY(field == nullptr || obj == nullptr)) {                        \
      if (IsObject) {                                                          \
        StackHandleScope<1> hs(self);                                          \
        HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(               \
            reinterpret_cast<mirror::Object**>(&new_value)));                  \
        field =                                                                \
            FindInstanceField<Instance ## PrimitiveOrObject ## Write, true>(   \
                field_idx,                                                     \
                referrer,                                                      \
                self,                                                          \
                sizeof(PrimitiveType),                                         \
                &obj);                                                         \
      } else {                                                                 \
        field =                                                                \
            FindInstanceField<Instance ## PrimitiveOrObject ## Write, true>(   \
                field_idx,                                                     \
                referrer,                                                      \
                self,                                                          \
                sizeof(PrimitiveType),                                         \
                &obj);                                                         \
      }                                                                        \
      if (UNLIKELY(field == nullptr)) {                                        \
        return -1;                                                             \
      }                                                                        \
    }                                                                          \
    if (!referrer->SkipAccessChecks() && IsObject && new_value != 0) {         \
      StackArtFieldHandleScope<1> rhs(self);                                   \
      ReflectiveHandle<ArtField> field_handle(rhs.NewHandle(field));           \
      if (field->ResolveType().IsNull()) {                                     \
        self->AssertPendingException();                                        \
        return -1;                                                             \
      }                                                                        \
      field = field_handle.Get();                                              \
    }                                                                          \
    field->Set ## Kind<false>(obj, new_value);                                 \
    return 0;                                                                  \
  }                                                                            \
                                                                               \
  extern "C" RetType artGet ## Kind ## StaticFromCompiledCode(                 \
      uint32_t field_idx,                                                      \
      Thread* self)                                                            \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    return artGet ## Kind ## StaticFromCode(                                   \
        field_idx, GetReferrer(self), self);                                   \
  }                                                                            \
                                                                               \
  extern "C" RetType artGet ## Kind ## InstanceFromCompiledCode(               \
      uint32_t field_idx,                                                      \
      mirror::Object* obj,                                                     \
      Thread* self)                                                            \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    return artGet ## Kind ## InstanceFromCode(                                 \
        field_idx, obj, GetReferrer(self), self);                              \
  }                                                                            \
                                                                               \
  extern "C" int artSet ## Kind ## StaticFromCompiledCode(                     \
      uint32_t field_idx,                                                      \
      SetType new_value,                                                       \
      Thread* self)                                                            \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    return artSet ## Kind ## StaticFromCode(                                   \
        field_idx, new_value, GetReferrer(self), self);                        \
  }                                                                            \
                                                                               \
  extern "C" int artSet ## Kind ## InstanceFromCompiledCode(                   \
      uint32_t field_idx,                                                      \
      mirror::Object* obj,                                                     \
      SetType new_value,                                                       \
      Thread* self)                                                            \
      REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
    return artSet ## Kind ## InstanceFromCode(                                 \
        field_idx, obj, new_value, GetReferrer(self), self);                   \
  }

// Define these functions:
//
//   artGetByteStaticFromCode
//   artGetByteInstanceFromCode
//   artSetByteStaticFromCode
//   artSetByteInstanceFromCode
//   artGetByteStaticFromCompiledCode
//   artGetByteInstanceFromCompiledCode
//   artSetByteStaticFromCompiledCode
//   artSetByteInstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(Byte, int8_t, ssize_t, uint32_t, Primitive, false, )

// Define these functions:
//
//   artGetBooleanStaticFromCode
//   artGetBooleanInstanceFromCode
//   artSetBooleanStaticFromCode
//   artSetBooleanInstanceFromCode
//   artGetBooleanStaticFromCompiledCode
//   artGetBooleanInstanceFromCompiledCode
//   artSetBooleanStaticFromCompiledCode
//   artSetBooleanInstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(Boolean, int8_t, size_t, uint32_t, Primitive, false, )

// Define these functions:
//
//   artGetShortStaticFromCode
//   artGetShortInstanceFromCode
//   artSetShortStaticFromCode
//   artSetShortInstanceFromCode
//   artGetShortStaticFromCompiledCode
//   artGetShortInstanceFromCompiledCode
//   artSetShortStaticFromCompiledCode
//   artSetShortInstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(Short, int16_t, ssize_t, uint16_t, Primitive, false, )

// Define these functions:
//
//   artGetCharStaticFromCode
//   artGetCharInstanceFromCode
//   artSetCharStaticFromCode
//   artSetCharInstanceFromCode
//   artGetCharStaticFromCompiledCode
//   artGetCharInstanceFromCompiledCode
//   artSetCharStaticFromCompiledCode
//   artSetCharInstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(Char, int16_t, size_t, uint16_t, Primitive, false, )

// Define these functions:
//
//   artGet32StaticFromCode
//   artGet32InstanceFromCode
//   artSet32StaticFromCode
//   artSet32InstanceFromCode
//   artGet32StaticFromCompiledCode
//   artGet32InstanceFromCompiledCode
//   artSet32StaticFromCompiledCode
//   artSet32InstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(32, int32_t, size_t, uint32_t, Primitive, false, )

// Define these functions:
//
//   artGet64StaticFromCode
//   artGet64InstanceFromCode
//   artSet64StaticFromCode
//   artSet64InstanceFromCode
//   artGet64StaticFromCompiledCode
//   artGet64InstanceFromCompiledCode
//   artSet64StaticFromCompiledCode
//   artSet64InstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(64, int64_t, uint64_t, uint64_t, Primitive, false, )

// Define these functions:
//
//   artGetObjStaticFromCode
//   artGetObjInstanceFromCode
//   artSetObjStaticFromCode
//   artSetObjInstanceFromCode
//   artGetObjStaticFromCompiledCode
//   artGetObjInstanceFromCompiledCode
//   artSetObjStaticFromCompiledCode
//   artSetObjInstanceFromCompiledCode
//
ART_GET_FIELD_FROM_CODE(Obj, mirror::HeapReference<mirror::Object>, mirror::Object*,
                        mirror::Object*, Object, true, .Ptr())

#undef ART_GET_FIELD_FROM_CODE


// To cut on the number of entrypoints, we have shared entries for
// byte/boolean and char/short for setting an instance or static field. We just
// forward those to the unsigned variant.
extern "C" int artSet8StaticFromCompiledCode(uint32_t field_idx,
                                             uint32_t new_value,
                                             Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetBooleanStaticFromCode(field_idx, new_value, GetReferrer(self), self);
}

extern "C" int artSet16StaticFromCompiledCode(uint32_t field_idx,
                                              uint16_t new_value,
                                              Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetCharStaticFromCode(field_idx, new_value, GetReferrer(self), self);
}

extern "C" int artSet8InstanceFromCompiledCode(uint32_t field_idx,
                                               mirror::Object* obj,
                                               uint8_t new_value,
                                               Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetBooleanInstanceFromCode(field_idx, obj, new_value, GetReferrer(self), self);
}

extern "C" int artSet16InstanceFromCompiledCode(uint32_t field_idx,
                                                mirror::Object* obj,
                                                uint16_t new_value,
                                                Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetCharInstanceFromCode(field_idx, obj, new_value, GetReferrer(self), self);
}

extern "C" int artSet8StaticFromCode(uint32_t field_idx,
                                     uint32_t new_value,
                                     ArtMethod* referrer,
                                     Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetBooleanStaticFromCode(field_idx, new_value, referrer, self);
}

extern "C" int artSet16StaticFromCode(uint32_t field_idx,
                                      uint16_t new_value,
                                      ArtMethod* referrer,
                                      Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetCharStaticFromCode(field_idx, new_value, referrer, self);
}

extern "C" int artSet8InstanceFromCode(uint32_t field_idx,
                                       mirror::Object* obj,
                                       uint8_t new_value,
                                       ArtMethod* referrer,
                                       Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetBooleanInstanceFromCode(field_idx, obj, new_value, referrer, self);
}

extern "C" int artSet16InstanceFromCode(uint32_t field_idx,
                                        mirror::Object* obj,
                                        uint16_t new_value,
                                        ArtMethod* referrer,
                                        Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  return artSetCharInstanceFromCode(field_idx, obj, new_value, referrer, self);
}

extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj) {
  DCHECK(kEmitCompilerReadBarrier);
  return ReadBarrier::Mark(obj);
}

extern "C" mirror::Object* artReadBarrierSlow(mirror::Object* ref ATTRIBUTE_UNUSED,
                                              mirror::Object* obj,
                                              uint32_t offset) {
  // Used only in connection with non-volatile loads.
  DCHECK(kEmitCompilerReadBarrier);
  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(obj) + offset;
  mirror::HeapReference<mirror::Object>* ref_addr =
     reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
  constexpr ReadBarrierOption kReadBarrierOption =
      kUseReadBarrier ? kWithReadBarrier : kWithoutReadBarrier;
  mirror::Object* result =
      ReadBarrier::Barrier<mirror::Object, /* kIsVolatile= */ false, kReadBarrierOption>(
        obj,
        MemberOffset(offset),
        ref_addr);
  return result;
}

extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root) {
  DCHECK(kEmitCompilerReadBarrier);
  return root->Read();
}

}  // namespace art
