1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * Template types for use in generic code: to use Rooted/Handle/MutableHandle in
9 * cases where GC may occur, or to use mock versions of those types that perform
10 * no rooting or root list manipulation when GC cannot occur.
13 #ifndef gc_MaybeRooted_h
14 #define gc_MaybeRooted_h
16 #include "mozilla/Attributes.h" // MOZ_IMPLICIT, MOZ_RAII
18 #include <type_traits> // std::true_type
20 #include "gc/GCEnum.h" // js::AllowGC, js::CanGC, js::NoGC
21 #include "js/ComparisonOperators.h" // JS::detail::DefineComparisonOps
22 #include "js/RootingAPI.h" // js::{Rooted,MutableHandle}Base, JS::SafelyInitialized, DECLARE_POINTER_{CONSTREF,ASSIGN}_OPS, DECLARE_NONPOINTER_{,MUTABLE_}ACCESSOR_METHODS, JS::Rooted, JS::{,Mutable}Handle
27 * Interface substitute for Rooted<T> which does not root the variable's
31 class MOZ_RAII FakeRooted
: public RootedOperations
<T
, FakeRooted
<T
>> {
33 using ElementType
= T
;
35 explicit FakeRooted(JSContext
* cx
)
36 : ptr(JS::SafelyInitialized
<T
>::create()) {}
38 FakeRooted(JSContext
* cx
, const T
& initial
) : ptr(initial
) {}
40 FakeRooted(const FakeRooted
&) = delete;
42 DECLARE_POINTER_CONSTREF_OPS(T
);
43 DECLARE_POINTER_ASSIGN_OPS(FakeRooted
, T
);
44 DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr
);
45 DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr
);
47 operator JS::Handle
<T
>() { return JS::Handle
<T
>::fromMarkedLocation(&ptr
); }
52 void set(const T
& value
) { ptr
= value
; }
57 namespace JS::detail
{
59 struct DefineComparisonOps
<js::FakeRooted
<T
>> : std::true_type
{
60 static const T
& get(const js::FakeRooted
<T
>& v
) { return v
.get(); }
62 } // namespace JS::detail
67 * Interface substitute for MutableHandle<T> which is not required to point to
71 class FakeMutableHandle
72 : public js::MutableHandleOperations
<T
, FakeMutableHandle
<T
>> {
74 using ElementType
= T
;
76 MOZ_IMPLICIT
FakeMutableHandle(T
* t
) : ptr(t
) {}
78 MOZ_IMPLICIT
FakeMutableHandle(FakeRooted
<T
>* root
) : ptr(root
->address()) {}
80 void set(const T
& v
) { *ptr
= v
; }
82 DECLARE_POINTER_CONSTREF_OPS(T
);
83 DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr
);
84 DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr
);
87 FakeMutableHandle() : ptr(nullptr) {}
88 DELETE_ASSIGNMENT_OPS(FakeMutableHandle
, T
);
95 namespace JS::detail
{
97 struct DefineComparisonOps
<js::FakeMutableHandle
<T
>> : std::true_type
{
98 static const T
& get(const js::FakeMutableHandle
<T
>& v
) { return v
.get(); }
100 } // namespace JS::detail
105 * Types for a variable that either should or shouldn't be rooted, depending on
106 * the template parameter allowGC. Used for implementing functions that can
107 * operate on either rooted or unrooted data.
110 template <typename T
, AllowGC allowGC
>
113 template <typename T
>
114 class MaybeRooted
<T
, CanGC
> {
116 using HandleType
= JS::Handle
<T
>;
117 using RootType
= JS::Rooted
<T
>;
118 using MutableHandleType
= JS::MutableHandle
<T
>;
121 template <typename T
>
122 class MaybeRooted
<T
, NoGC
> {
124 using HandleType
= const T
&;
125 using RootType
= FakeRooted
<T
>;
126 using MutableHandleType
= FakeMutableHandle
<T
>;
131 #endif // gc_MaybeRooted_h