// Copyright 2018 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_MAYBE_OBJECT_H_
#define V8_OBJECTS_MAYBE_OBJECT_H_

#include "include/v8-internal.h"
#include "include/v8.h"
#include "src/globals.h"
#include "src/objects.h"
#include "src/objects/slots.h"
#include "src/objects/smi.h"

namespace v8 {
namespace internal {

class HeapObject;
class Isolate;
class StringStream;

// A MaybeObject is either a SMI, a strong reference to a HeapObject, a weak
// reference to a HeapObject, or a cleared weak reference. It's used for
// implementing in-place weak references (see design doc: goo.gl/j6SdcK )
class MaybeObject {
 public:
  MaybeObject() : ptr_(kNullAddress) {}
  explicit MaybeObject(Address ptr) : ptr_(ptr) {}

  bool operator==(const MaybeObject& other) const { return ptr_ == other.ptr_; }
  bool operator!=(const MaybeObject& other) const { return ptr_ != other.ptr_; }

  Address ptr() const { return ptr_; }

  // Enable incremental transition of client code.
  MaybeObject* operator->() { return this; }
  const MaybeObject* operator->() const { return this; }

  bool IsSmi() const { return HAS_SMI_TAG(ptr_); }
  inline bool ToSmi(Smi* value);
  inline Smi ToSmi() const;

  bool IsCleared() const {
    return static_cast<uint32_t>(ptr_) == kClearedWeakHeapObjectLower32;
  }

  inline bool IsStrongOrWeak() const;
  inline bool IsStrong() const;

  // If this MaybeObject is a strong pointer to a HeapObject, returns true and
  // sets *result. Otherwise returns false.
  inline bool GetHeapObjectIfStrong(HeapObject* result) const;

  // DCHECKs that this MaybeObject is a strong pointer to a HeapObject and
  // returns the HeapObject.
  inline HeapObject GetHeapObjectAssumeStrong() const;

  inline bool IsWeak() const;
  inline bool IsWeakOrCleared() const;

  // If this MaybeObject is a weak pointer to a HeapObject, returns true and
  // sets *result. Otherwise returns false.
  inline bool GetHeapObjectIfWeak(HeapObject* result) const;

  // DCHECKs that this MaybeObject is a weak pointer to a HeapObject and
  // returns the HeapObject.
  inline HeapObject GetHeapObjectAssumeWeak() const;

  // If this MaybeObject is a strong or weak pointer to a HeapObject, returns
  // true and sets *result. Otherwise returns false.
  inline bool GetHeapObject(HeapObject* result) const;
  inline bool GetHeapObject(HeapObject* result,
                            HeapObjectReferenceType* reference_type) const;

  // DCHECKs that this MaybeObject is a strong or a weak pointer to a HeapObject
  // and returns the HeapObject.
  inline HeapObject GetHeapObject() const;

  // DCHECKs that this MaybeObject is a strong or a weak pointer to a HeapObject
  // or a SMI and returns the HeapObject or SMI.
  inline Object* GetHeapObjectOrSmi() const;

  inline bool IsObject() const;
  template <typename T, typename = typename std::enable_if<
                            std::is_base_of<Object, T>::value>::type>
  T* cast() const {
    DCHECK(!HasWeakHeapObjectTag(ptr_));
    return T::cast(reinterpret_cast<Object*>(ptr_));
  }
  // Replacement for the above, temporarily separate for incremental transition.
  // TODO(3770): Get rid of the duplication.
  template <typename T, typename = typename std::enable_if<
                            std::is_base_of<ObjectPtr, T>::value>::type>
  T cast() const {
    DCHECK(!HasWeakHeapObjectTag(ptr_));
    return T::cast(ObjectPtr(ptr_));
  }

  static MaybeObject FromSmi(Smi smi) {
    DCHECK(HAS_SMI_TAG(smi->ptr()));
    return MaybeObject(smi->ptr());
  }

  static MaybeObject FromObject(Object* object) {
    DCHECK(!HasWeakHeapObjectTag(object));
    return MaybeObject(object->ptr());
  }

  static MaybeObject FromObject(ObjectPtr object) {
    DCHECK(!HasWeakHeapObjectTag(object.ptr()));
    return MaybeObject(object.ptr());
  }

  static inline MaybeObject MakeWeak(MaybeObject object);

#ifdef VERIFY_HEAP
  static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p);
#endif

  // Prints this object without details.
  void ShortPrint(FILE* out = stdout);

  // Prints this object without details to a message accumulator.
  void ShortPrint(StringStream* accumulator);

  void ShortPrint(std::ostream& os);

#ifdef OBJECT_PRINT
  void Print();
  void Print(std::ostream& os);
#else
  void Print() { ShortPrint(); }
  void Print(std::ostream& os) { ShortPrint(os); }
#endif

 private:
  Address ptr_;
};

// A HeapObjectReference is either a strong reference to a HeapObject, a weak
// reference to a HeapObject, or a cleared weak reference.
class HeapObjectReference : public MaybeObject {
 public:
  explicit HeapObjectReference(Address address) : MaybeObject(address) {}
  explicit HeapObjectReference(Object* object) : MaybeObject(object->ptr()) {}

  static HeapObjectReference Strong(Object* object) {
    DCHECK(!object->IsSmi());
    DCHECK(!HasWeakHeapObjectTag(object));
    return HeapObjectReference(object);
  }

  static HeapObjectReference Weak(Object* object) {
    DCHECK(!object->IsSmi());
    DCHECK(!HasWeakHeapObjectTag(object));
    return HeapObjectReference(object->ptr() | kWeakHeapObjectMask);
  }

  V8_INLINE static HeapObjectReference ClearedValue(Isolate* isolate);

  template <typename THeapObjectSlot>
  V8_INLINE static void Update(THeapObjectSlot slot, HeapObject value);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_MAYBE_OBJECT_H_
