Handle.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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/Badge.h>
  8. #include <AK/IntrusiveList.h>
  9. #include <AK/Noncopyable.h>
  10. #include <AK/RefCounted.h>
  11. #include <AK/RefPtr.h>
  12. #include <LibJS/Forward.h>
  13. #include <LibJS/Runtime/Environment.h>
  14. #include <LibJS/Runtime/Value.h>
  15. namespace JS {
  16. class HandleImpl : public RefCounted<HandleImpl> {
  17. AK_MAKE_NONCOPYABLE(HandleImpl);
  18. AK_MAKE_NONMOVABLE(HandleImpl);
  19. public:
  20. ~HandleImpl();
  21. Cell* cell() { return m_cell; }
  22. const Cell* cell() const { return m_cell; }
  23. private:
  24. template<class T>
  25. friend class Handle;
  26. explicit HandleImpl(Cell*);
  27. Cell* m_cell { nullptr };
  28. IntrusiveListNode<HandleImpl> m_list_node;
  29. public:
  30. using List = IntrusiveList<&HandleImpl::m_list_node>;
  31. };
  32. template<class T>
  33. class Handle {
  34. public:
  35. Handle() = default;
  36. static Handle create(T* cell)
  37. {
  38. return Handle(adopt_ref(*new HandleImpl(cell)));
  39. }
  40. T* cell() { return static_cast<T*>(m_impl->cell()); }
  41. const T* cell() const { return static_cast<const T*>(m_impl->cell()); }
  42. bool is_null() const { return m_impl.is_null(); }
  43. T* operator->() { return cell(); }
  44. T const* operator->() const { return cell(); }
  45. private:
  46. explicit Handle(NonnullRefPtr<HandleImpl> impl)
  47. : m_impl(move(impl))
  48. {
  49. }
  50. RefPtr<HandleImpl> m_impl;
  51. };
  52. template<class T>
  53. inline Handle<T> make_handle(T* cell)
  54. {
  55. return Handle<T>::create(cell);
  56. }
  57. template<class T>
  58. inline Handle<T> make_handle(T& cell)
  59. {
  60. return Handle<T>::create(&cell);
  61. }
  62. template<>
  63. class Handle<Value> {
  64. public:
  65. Handle() = default;
  66. static Handle create(Value value)
  67. {
  68. if (value.is_cell())
  69. return Handle(value, &value.as_cell());
  70. return Handle(value);
  71. }
  72. auto cell() { return m_handle.cell(); }
  73. auto cell() const { return m_handle.cell(); }
  74. auto value() const { return m_value; }
  75. bool is_null() const { return m_handle.is_null(); }
  76. private:
  77. explicit Handle(Value value)
  78. : m_value(value)
  79. {
  80. }
  81. explicit Handle(Value value, Cell* cell)
  82. : m_value(value)
  83. , m_handle(Handle<Cell>::create(cell))
  84. {
  85. }
  86. Value m_value;
  87. Handle<Cell> m_handle;
  88. };
  89. inline Handle<Value> make_handle(Value value)
  90. {
  91. return Handle<Value>::create(value);
  92. }
  93. }