Cell.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Format.h>
  8. #include <AK/Forward.h>
  9. #include <AK/Noncopyable.h>
  10. #include <AK/StringView.h>
  11. #include <LibJS/Forward.h>
  12. #include <LibJS/Heap/GCPtr.h>
  13. namespace JS {
  14. #define JS_CELL(class_, base_class) \
  15. public: \
  16. using Base = base_class; \
  17. virtual StringView class_name() const override \
  18. { \
  19. return #class_##sv; \
  20. } \
  21. friend class JS::Heap;
  22. class Cell {
  23. AK_MAKE_NONCOPYABLE(Cell);
  24. AK_MAKE_NONMOVABLE(Cell);
  25. public:
  26. virtual void initialize(Realm&) { }
  27. virtual ~Cell() = default;
  28. bool is_marked() const { return m_mark; }
  29. void set_marked(bool b) { m_mark = b; }
  30. enum class State {
  31. Live,
  32. Dead,
  33. };
  34. State state() const { return m_state; }
  35. void set_state(State state) { m_state = state; }
  36. virtual StringView class_name() const = 0;
  37. class Visitor {
  38. public:
  39. void visit(Cell* cell)
  40. {
  41. if (cell)
  42. visit_impl(*cell);
  43. }
  44. void visit(Cell& cell)
  45. {
  46. visit_impl(cell);
  47. }
  48. template<typename T>
  49. void visit(GCPtr<T> cell)
  50. {
  51. if (cell)
  52. visit_impl(*cell.ptr());
  53. }
  54. template<typename T>
  55. void visit(NonnullGCPtr<T> cell)
  56. {
  57. visit_impl(*cell.ptr());
  58. }
  59. void visit(Value);
  60. protected:
  61. virtual void visit_impl(Cell&) = 0;
  62. virtual ~Visitor() = default;
  63. };
  64. virtual bool is_environment() const { return false; }
  65. virtual void visit_edges(Visitor&) { }
  66. Heap& heap() const;
  67. VM& vm() const;
  68. protected:
  69. Cell() = default;
  70. private:
  71. bool m_mark : 1 { false };
  72. State m_state : 7 { State::Live };
  73. };
  74. }
  75. template<>
  76. struct AK::Formatter<JS::Cell> : AK::Formatter<FormatString> {
  77. ErrorOr<void> format(FormatBuilder& builder, JS::Cell const* cell)
  78. {
  79. if (!cell)
  80. return builder.put_string("Cell{nullptr}"sv);
  81. return Formatter<FormatString>::format(builder, "{}({})"sv, cell->class_name(), cell);
  82. }
  83. };