Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / public / Object.h
blobc7c5e3c61794a87a2a31c02b9aa1bcf16eb0f1cc
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 #ifndef js_public_Object_h
8 #define js_public_Object_h
10 #include "js/shadow/Object.h" // JS::shadow::Object
12 #include "mozilla/Assertions.h" // MOZ_ASSERT
14 #include <stddef.h> // size_t
15 #include <stdint.h> // uint32_t
17 #include "jstypes.h" // JS_PUBLIC_API
19 #include "js/Class.h" // js::ESClass, JSCLASS_RESERVED_SLOTS
20 #include "js/Realm.h" // JS::GetCompartmentForRealm
21 #include "js/RootingAPI.h" // JS::{,Mutable}Handle
22 #include "js/Value.h" // JS::Value
24 struct JS_PUBLIC_API JSContext;
25 class JS_PUBLIC_API JSObject;
27 namespace JS {
29 class JS_PUBLIC_API Compartment;
31 /**
32 * Determine the ECMAScript "class" -- Date, String, RegExp, and all the other
33 * builtin object types (described in ECMAScript in terms of an objecting having
34 * "an [[ArrayBufferData]] internal slot" or similar language for other kinds of
35 * object -- of the provided object.
37 * If this function is passed a wrapper that can be unwrapped, the determination
38 * is performed on that object. If the wrapper can't be unwrapped, and it's not
39 * a wrapper that prefers to treat this operation as a failure, this function
40 * will indicate that the object is |js::ESClass::Other|.
42 extern JS_PUBLIC_API bool GetBuiltinClass(JSContext* cx, Handle<JSObject*> obj,
43 js::ESClass* cls);
45 /** Get the |JSClass| of an object. */
46 inline const JSClass* GetClass(const JSObject* obj) {
47 return reinterpret_cast<const shadow::Object*>(obj)->shape->base->clasp;
50 /**
51 * Get the |JS::Compartment*| of an object.
53 * Note that the compartment of an object in this realm, that is a
54 * cross-compartment wrapper around an object from another realm, is the
55 * compartment of this realm.
57 static MOZ_ALWAYS_INLINE Compartment* GetCompartment(JSObject* obj) {
58 Realm* realm = reinterpret_cast<shadow::Object*>(obj)->shape->base->realm;
59 return GetCompartmentForRealm(realm);
62 /**
63 * Get the value stored in a reserved slot in an object.
65 * If |obj| is known to be a proxy and you're willing to use friend APIs,
66 * |js::GetProxyReservedSlot| in "js/Proxy.h" is very slightly more efficient.
68 inline const Value& GetReservedSlot(JSObject* obj, size_t slot) {
69 MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetClass(obj)));
70 return reinterpret_cast<const shadow::Object*>(obj)->slotRef(slot);
73 namespace detail {
75 extern JS_PUBLIC_API void SetReservedSlotWithBarrier(JSObject* obj, size_t slot,
76 const Value& value);
78 } // namespace detail
80 /**
81 * Store a value in an object's reserved slot.
83 * This can be used with both native objects and proxies. However, if |obj| is
84 * known to be a proxy, |js::SetProxyReservedSlot| in "js/Proxy.h" is very
85 * slightly more efficient.
87 inline void SetReservedSlot(JSObject* obj, size_t slot, const Value& value) {
88 MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetClass(obj)));
89 auto* sobj = reinterpret_cast<shadow::Object*>(obj);
90 if (sobj->slotRef(slot).isGCThing() || value.isGCThing()) {
91 detail::SetReservedSlotWithBarrier(obj, slot, value);
92 } else {
93 sobj->slotRef(slot) = value;
97 /**
98 * Helper function to get the pointer value (or nullptr if not set) from an
99 * object's reserved slot. The slot must contain either a PrivateValue(T*) or
100 * UndefinedValue.
102 template <typename T>
103 inline T* GetMaybePtrFromReservedSlot(JSObject* obj, size_t slot) {
104 Value v = GetReservedSlot(obj, slot);
105 return v.isUndefined() ? nullptr : static_cast<T*>(v.toPrivate());
109 * Helper function to get the pointer value (or nullptr if not set) from the
110 * object's first reserved slot. Must only be used for objects with a JSClass
111 * that has the JSCLASS_SLOT0_IS_NSISUPPORTS flag.
113 template <typename T>
114 inline T* GetObjectISupports(JSObject* obj) {
115 MOZ_ASSERT(GetClass(obj)->slot0IsISupports());
116 return GetMaybePtrFromReservedSlot<T>(obj, 0);
120 * Helper function to store |PrivateValue(nsISupportsValue)| in the object's
121 * first reserved slot. Must only be used for objects with a JSClass that has
122 * the JSCLASS_SLOT0_IS_NSISUPPORTS flag.
124 * Note: the pointer is opaque to the JS engine (including the GC) so it's the
125 * embedding's responsibility to trace or free this value.
127 inline void SetObjectISupports(JSObject* obj, void* nsISupportsValue) {
128 MOZ_ASSERT(GetClass(obj)->slot0IsISupports());
129 SetReservedSlot(obj, 0, PrivateValue(nsISupportsValue));
132 } // namespace JS
134 // JSObject* is an aligned pointer, but this information isn't available in the
135 // public header. We specialize HasFreeLSB here so that JS::Result<JSObject*>
136 // compiles.
138 namespace mozilla {
139 namespace detail {
140 template <>
141 struct HasFreeLSB<JSObject*> {
142 static constexpr bool value = true;
144 } // namespace detail
145 } // namespace mozilla
147 #endif // js_public_Object_h