// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_TAGGED_FIELD_INL_H_
#define V8_OBJECTS_TAGGED_FIELD_INL_H_

#include "src/objects/tagged-field.h"

#include "src/common/ptr-compr-inl.h"

namespace v8 {
namespace internal {

// static
template <typename T, int kFieldOffset>
Address TaggedField<T, kFieldOffset>::address(HeapObject host, int offset) {
  return host.address() + kFieldOffset + offset;
}

// static
template <typename T, int kFieldOffset>
Tagged_t* TaggedField<T, kFieldOffset>::location(HeapObject host, int offset) {
  return reinterpret_cast<Tagged_t*>(address(host, offset));
}

// static
template <typename T, int kFieldOffset>
template <typename TOnHeapAddress>
Address TaggedField<T, kFieldOffset>::tagged_to_full(
    TOnHeapAddress on_heap_addr, Tagged_t tagged_value) {
#ifdef V8_COMPRESS_POINTERS
  if (kIsSmi) {
    return DecompressTaggedSigned(tagged_value);
  } else if (kIsHeapObject) {
    return DecompressTaggedPointer(on_heap_addr, tagged_value);
  } else {
    return DecompressTaggedAny(on_heap_addr, tagged_value);
  }
#else
  return tagged_value;
#endif
}

// static
template <typename T, int kFieldOffset>
Tagged_t TaggedField<T, kFieldOffset>::full_to_tagged(Address value) {
#ifdef V8_COMPRESS_POINTERS
  return CompressTagged(value);
#else
  return value;
#endif
}

// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::load(HeapObject host, int offset) {
  Tagged_t value = *location(host, offset);
  return T(tagged_to_full(host.ptr(), value));
}

// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::load(IsolateRoot isolate, HeapObject host,
                                     int offset) {
  Tagged_t value = *location(host, offset);
  return T(tagged_to_full(isolate, value));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::store(HeapObject host, T value) {
#ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
  Relaxed_Store(host, value);
#else
  *location(host) = full_to_tagged(value.ptr());
#endif
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::store(HeapObject host, int offset, T value) {
#ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
  Relaxed_Store(host, offset, value);
#else
  *location(host, offset) = full_to_tagged(value.ptr());
#endif
}

// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host, int offset) {
  AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
  return T(tagged_to_full(host.ptr(), value));
}

// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Relaxed_Load(IsolateRoot isolate,
                                             HeapObject host, int offset) {
  AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
  return T(tagged_to_full(isolate, value));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, T value) {
  AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(value.ptr()));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, int offset,
                                                 T value) {
  AsAtomicTagged::Relaxed_Store(location(host, offset),
                                full_to_tagged(value.ptr()));
}

// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host, int offset) {
  AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
  return T(tagged_to_full(host.ptr(), value));
}

// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Acquire_Load(IsolateRoot isolate,
                                             HeapObject host, int offset) {
  AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
  return T(tagged_to_full(isolate, value));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, T value) {
  AsAtomicTagged::Release_Store(location(host), full_to_tagged(value.ptr()));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, int offset,
                                                 T value) {
  AsAtomicTagged::Release_Store(location(host, offset),
                                full_to_tagged(value.ptr()));
}

// static
template <typename T, int kFieldOffset>
Tagged_t TaggedField<T, kFieldOffset>::Release_CompareAndSwap(HeapObject host,
                                                              T old, T value) {
  Tagged_t old_value = full_to_tagged(old.ptr());
  Tagged_t new_value = full_to_tagged(value.ptr());
  Tagged_t result = AsAtomicTagged::Release_CompareAndSwap(
      location(host), old_value, new_value);
  return result;
}

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_TAGGED_FIELD_INL_H_
