no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / js / src / gc / MaybeRooted.h
blob6b38172472d23451b19c6fed20daf01ce3cf9aaa
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/. */
7 /*
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
24 namespace js {
26 /**
27 * Interface substitute for Rooted<T> which does not root the variable's
28 * memory.
30 template <typename T>
31 class MOZ_RAII FakeRooted : public RootedOperations<T, FakeRooted<T>> {
32 public:
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); }
49 private:
50 T ptr;
52 void set(const T& value) { ptr = value; }
55 } // namespace js
57 namespace JS::detail {
58 template <typename T>
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
64 namespace js {
66 /**
67 * Interface substitute for MutableHandle<T> which is not required to point to
68 * rooted memory.
70 template <typename T>
71 class FakeMutableHandle
72 : public js::MutableHandleOperations<T, FakeMutableHandle<T>> {
73 public:
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);
86 private:
87 FakeMutableHandle() : ptr(nullptr) {}
88 DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T);
90 T* ptr;
93 } // namespace js
95 namespace JS::detail {
96 template <typename T>
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
102 namespace js {
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>
111 class MaybeRooted;
113 template <typename T>
114 class MaybeRooted<T, CanGC> {
115 public:
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> {
123 public:
124 using HandleType = const T&;
125 using RootType = FakeRooted<T>;
126 using MutableHandleType = FakeMutableHandle<T>;
129 } // namespace js
131 #endif // gc_MaybeRooted_h