// 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_JS_WEAK_REFS_H_
#define V8_OBJECTS_JS_WEAK_REFS_H_

#include "src/objects/js-objects.h"
#include "src/objects/microtask.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

class NativeContext;
class WeakCell;

// FinalizationGroup object from the JS Weak Refs spec proposal:
// https://github.com/tc39/proposal-weakrefs
class JSFinalizationGroup : public JSObject {
 public:
  DECL_PRINTER(JSFinalizationGroup)
  EXPORT_DECL_VERIFIER(JSFinalizationGroup)
  DECL_CAST(JSFinalizationGroup)

  DECL_ACCESSORS(native_context, NativeContext)
  DECL_ACCESSORS(cleanup, Object)

  DECL_ACCESSORS(active_cells, Object)
  DECL_ACCESSORS(cleared_cells, Object)
  DECL_ACCESSORS(key_map, Object)

  // For storing a list of JSFinalizationGroup objects in NativeContext.
  DECL_ACCESSORS(next, Object)

  DECL_INT_ACCESSORS(flags)

  inline static void Register(Handle<JSFinalizationGroup> finalization_group,
                              Handle<JSReceiver> target,
                              Handle<Object> holdings, Handle<Object> key,
                              Isolate* isolate);
  inline static bool Unregister(Handle<JSFinalizationGroup> finalization_group,
                                Handle<JSReceiver> unregister_token,
                                Isolate* isolate);

  // Returns true if the cleared_cells list is non-empty.
  inline bool NeedsCleanup() const;

  inline bool scheduled_for_cleanup() const;
  inline void set_scheduled_for_cleanup(bool scheduled_for_cleanup);

  // Remove the first cleared WeakCell from the cleared_cells
  // list (assumes there is one) and return its holdings.
  inline static Object PopClearedCellHoldings(
      Handle<JSFinalizationGroup> finalization_group, Isolate* isolate);

  // Constructs an iterator for the WeakCells in the cleared_cells list and
  // calls the user's cleanup function.
  static void Cleanup(Isolate* isolate,
                      Handle<JSFinalizationGroup> finalization_group,
                      Handle<Object> callback);

  // Layout description.
  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
                                TORQUE_GENERATED_JSFINALIZATION_GROUP_FIELDS)

  // Bitfields in flags.
  class ScheduledForCleanupField : public BitField<bool, 0, 1> {};

  OBJECT_CONSTRUCTORS(JSFinalizationGroup, JSObject);
};

// Internal object for storing weak references in JSFinalizationGroup.
class WeakCell : public HeapObject {
 public:
  DECL_PRINTER(WeakCell)
  EXPORT_DECL_VERIFIER(WeakCell)
  DECL_CAST(WeakCell)

  DECL_ACCESSORS(finalization_group, Object)
  DECL_ACCESSORS(target, HeapObject)
  DECL_ACCESSORS(holdings, Object)

  // For storing doubly linked lists of WeakCells in JSFinalizationGroup's
  // "active_cells" and "cleared_cells" lists.
  DECL_ACCESSORS(prev, Object)
  DECL_ACCESSORS(next, Object)

  // For storing doubly linked lists of WeakCells per key in
  // JSFinalizationGroup's key-based hashmap. WeakCell also needs to know its
  // key, so that we can remove the key from the key_map when we remove the last
  // WeakCell associated with it.
  DECL_ACCESSORS(key, Object)
  DECL_ACCESSORS(key_list_prev, Object)
  DECL_ACCESSORS(key_list_next, Object)

  // Layout description.
  DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
                                TORQUE_GENERATED_WEAK_CELL_FIELDS)

  class BodyDescriptor;

  // Nullify is called during GC and it modifies the pointers in WeakCell and
  // JSFinalizationGroup. Thus we need to tell the GC about the modified slots
  // via the gc_notify_updated_slot function. The normal write barrier is not
  // enough, since it's disabled before GC.
  inline void Nullify(
      Isolate* isolate,
      std::function<void(HeapObject object, ObjectSlot slot, Object target)>
          gc_notify_updated_slot);

  inline void RemoveFromFinalizationGroupCells(Isolate* isolate);

  OBJECT_CONSTRUCTORS(WeakCell, HeapObject);
};

class JSWeakRef : public JSObject {
 public:
  DECL_PRINTER(JSWeakRef)
  EXPORT_DECL_VERIFIER(JSWeakRef)
  DECL_CAST(JSWeakRef)

  DECL_ACCESSORS(target, HeapObject)

  // Layout description.
  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
                                TORQUE_GENERATED_JSWEAK_REF_FIELDS)

  class BodyDescriptor;

  OBJECT_CONSTRUCTORS(JSWeakRef, JSObject);
};

class FinalizationGroupCleanupJobTask : public Microtask {
 public:
  DECL_ACCESSORS(finalization_group, JSFinalizationGroup)

  DECL_CAST(FinalizationGroupCleanupJobTask)
  DECL_VERIFIER(FinalizationGroupCleanupJobTask)
  DECL_PRINTER(FinalizationGroupCleanupJobTask)

// Layout description.
#define FINALIZATION_GROUP_CLEANUP_JOB_TASK_FIELDS(V) \
  V(kFinalizationGroupOffset, kTaggedSize)            \
  /* Total size. */                                   \
  V(kSize, 0)

  DEFINE_FIELD_OFFSET_CONSTANTS(Microtask::kHeaderSize,
                                FINALIZATION_GROUP_CLEANUP_JOB_TASK_FIELDS)
#undef FINALIZATION_GROUP_CLEANUP_JOB_TASK_FIELDS

  OBJECT_CONSTRUCTORS(FinalizationGroupCleanupJobTask, Microtask);
};

class JSFinalizationGroupCleanupIterator : public JSObject {
 public:
  DECL_PRINTER(JSFinalizationGroupCleanupIterator)
  DECL_VERIFIER(JSFinalizationGroupCleanupIterator)
  DECL_CAST(JSFinalizationGroupCleanupIterator)

  DECL_ACCESSORS(finalization_group, JSFinalizationGroup)

  // Layout description.
  DEFINE_FIELD_OFFSET_CONSTANTS(
    JSObject::kHeaderSize,
    TORQUE_GENERATED_JSFINALIZATION_GROUP_CLEANUP_ITERATOR_FIELDS)

  OBJECT_CONSTRUCTORS(JSFinalizationGroupCleanupIterator, JSObject);
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_JS_WEAK_REFS_H_
