summaryrefslogtreecommitdiffstats
path: root/js/src/gc/MaybeRooted.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /js/src/gc/MaybeRooted.h
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/gc/MaybeRooted.h')
-rw-r--r--js/src/gc/MaybeRooted.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/js/src/gc/MaybeRooted.h b/js/src/gc/MaybeRooted.h
new file mode 100644
index 0000000000..65373b467e
--- /dev/null
+++ b/js/src/gc/MaybeRooted.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Template types for use in generic code: to use Rooted/Handle/MutableHandle in
+ * cases where GC may occur, or to use mock versions of those types that perform
+ * no rooting or root list manipulation when GC cannot occur.
+ */
+
+#ifndef gc_MaybeRooted_h
+#define gc_MaybeRooted_h
+
+#include "mozilla/Attributes.h" // MOZ_IMPLICIT, MOZ_RAII
+
+#include <type_traits> // std::true_type
+
+#include "gc/Allocator.h" // js::AllowGC, js::CanGC, js::NoGC
+#include "js/ComparisonOperators.h" // JS::detail::DefineComparisonOps
+#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
+
+namespace js {
+
+/**
+ * Interface substitute for Rooted<T> which does not root the variable's
+ * memory.
+ */
+template <typename T>
+class MOZ_RAII FakeRooted : public RootedBase<T, FakeRooted<T>> {
+ public:
+ using ElementType = T;
+
+ template <typename CX>
+ explicit FakeRooted(CX* cx) : ptr(JS::SafelyInitialized<T>()) {}
+
+ template <typename CX>
+ FakeRooted(CX* cx, T initial) : ptr(initial) {}
+
+ DECLARE_POINTER_CONSTREF_OPS(T);
+ DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T);
+ DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
+ DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr);
+
+ private:
+ T ptr;
+
+ void set(const T& value) { ptr = value; }
+
+ FakeRooted(const FakeRooted&) = delete;
+};
+
+} // namespace js
+
+namespace JS {
+
+namespace detail {
+
+template <typename T>
+struct DefineComparisonOps<js::FakeRooted<T>> : std::true_type {
+ static const T& get(const js::FakeRooted<T>& v) { return v.get(); }
+};
+
+} // namespace detail
+
+} // namespace JS
+
+namespace js {
+
+/**
+ * Interface substitute for MutableHandle<T> which is not required to point to
+ * rooted memory.
+ */
+template <typename T>
+class FakeMutableHandle
+ : public js::MutableHandleBase<T, FakeMutableHandle<T>> {
+ public:
+ using ElementType = T;
+
+ MOZ_IMPLICIT FakeMutableHandle(T* t) : ptr(t) {}
+
+ MOZ_IMPLICIT FakeMutableHandle(FakeRooted<T>* root) : ptr(root->address()) {}
+
+ void set(const T& v) { *ptr = v; }
+
+ DECLARE_POINTER_CONSTREF_OPS(T);
+ DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
+ DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr);
+
+ private:
+ FakeMutableHandle() : ptr(nullptr) {}
+ DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T);
+
+ T* ptr;
+};
+
+} // namespace js
+
+namespace JS {
+
+namespace detail {
+
+template <typename T>
+struct DefineComparisonOps<js::FakeMutableHandle<T>> : std::true_type {
+ static const T& get(const js::FakeMutableHandle<T>& v) { return v.get(); }
+};
+
+} // namespace detail
+
+} // namespace JS
+
+namespace js {
+
+/**
+ * Types for a variable that either should or shouldn't be rooted, depending on
+ * the template parameter allowGC. Used for implementing functions that can
+ * operate on either rooted or unrooted data.
+ */
+
+template <typename T, AllowGC allowGC>
+class MaybeRooted;
+
+template <typename T>
+class MaybeRooted<T, CanGC> {
+ public:
+ using HandleType = JS::Handle<T>;
+ using RootType = JS::Rooted<T>;
+ using MutableHandleType = JS::MutableHandle<T>;
+
+ template <typename T2>
+ static JS::Handle<T2*> downcastHandle(HandleType v) {
+ return v.template as<T2>();
+ }
+};
+
+template <typename T>
+class MaybeRooted<T, NoGC> {
+ public:
+ using HandleType = const T&;
+ using RootType = FakeRooted<T>;
+ using MutableHandleType = FakeMutableHandle<T>;
+
+ template <typename T2>
+ static T2* downcastHandle(HandleType v) {
+ return &v->template as<T2>();
+ }
+};
+
+} // namespace js
+
+#endif // gc_MaybeRooted_h