1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsXBLMaybeCompiled_h__
7 #define nsXBLMaybeCompiled_h__
12 * A union containing either a pointer representing uncompiled source or a
13 * JSObject* representing the compiled result. The class is templated on the
16 * The purpose of abstracting this as a separate class is to allow it to be
17 * wrapped in a JS::Heap<T> to correctly handle post-barriering of the JSObject
18 * pointer, when present.
20 * No implementation of rootKind() is provided, which prevents
21 * Root<nsXBLMaybeCompiled<UncompiledT>> from being used.
23 template <class UncompiledT
>
24 class nsXBLMaybeCompiled
27 nsXBLMaybeCompiled() : mUncompiled(BIT_UNCOMPILED
) {}
29 explicit nsXBLMaybeCompiled(UncompiledT
* uncompiled
)
30 : mUncompiled(reinterpret_cast<uintptr_t>(uncompiled
) | BIT_UNCOMPILED
) {}
32 explicit nsXBLMaybeCompiled(JSObject
* compiled
) : mCompiled(compiled
) {}
34 bool IsCompiled() const
36 return !(mUncompiled
& BIT_UNCOMPILED
);
39 UncompiledT
* GetUncompiled() const
41 MOZ_ASSERT(!IsCompiled(), "Attempt to get compiled function as uncompiled");
42 uintptr_t unmasked
= mUncompiled
& ~BIT_UNCOMPILED
;
43 return reinterpret_cast<UncompiledT
*>(unmasked
);
46 JSObject
* GetJSFunction() const
48 MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
50 JS::ExposeObjectToActiveJS(mCompiled
);
55 // This is appropriate for use in tracing methods, etc.
56 JSObject
* GetJSFunctionPreserveColor() const
58 MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
63 JSObject
*& UnsafeGetJSFunction()
65 MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
69 enum { BIT_UNCOMPILED
= 1 << 0 };
73 // An pointer that represents the function before being compiled, with
74 // BIT_UNCOMPILED set.
75 uintptr_t mUncompiled
;
77 // The JS object for the compiled result.
81 friend struct js::GCMethods
<nsXBLMaybeCompiled
<UncompiledT
>>;
84 /* Add support for JS::Heap<nsXBLMaybeCompiled>. */
87 template <class UncompiledT
>
88 struct GCMethods
<nsXBLMaybeCompiled
<UncompiledT
> >
90 typedef struct GCMethods
<JSObject
*> Base
;
92 static nsXBLMaybeCompiled
<UncompiledT
> initial() { return nsXBLMaybeCompiled
<UncompiledT
>(); }
94 static bool poisoned(nsXBLMaybeCompiled
<UncompiledT
> function
)
96 return function
.IsCompiled() && Base::poisoned(function
.GetJSFunction());
99 static bool needsPostBarrier(nsXBLMaybeCompiled
<UncompiledT
> function
)
101 return function
.IsCompiled() && Base::needsPostBarrier(function
.GetJSFunction());
104 #ifdef JSGC_GENERATIONAL
105 static void postBarrier(nsXBLMaybeCompiled
<UncompiledT
>* functionp
)
107 Base::postBarrier(&functionp
->UnsafeGetJSFunction());
110 static void relocate(nsXBLMaybeCompiled
<UncompiledT
>* functionp
)
112 Base::relocate(&functionp
->UnsafeGetJSFunction());
117 template <class UncompiledT
>
118 class HeapBase
<nsXBLMaybeCompiled
<UncompiledT
> >
120 const JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >& wrapper() const {
121 return *static_cast<const JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >*>(this);
124 JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >& wrapper() {
125 return *static_cast<JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >*>(this);
128 const nsXBLMaybeCompiled
<UncompiledT
>* extract() const {
129 return wrapper().address();
132 nsXBLMaybeCompiled
<UncompiledT
>* extract() {
133 return wrapper().unsafeGet();
137 bool IsCompiled() const { return extract()->IsCompiled(); }
138 UncompiledT
* GetUncompiled() const { return extract()->GetUncompiled(); }
139 JSObject
* GetJSFunction() const { return extract()->GetJSFunction(); }
140 JSObject
* GetJSFunctionPreserveColor() const { return extract()->GetJSFunctionPreserveColor(); }
142 void SetUncompiled(UncompiledT
* source
) {
143 wrapper().set(nsXBLMaybeCompiled
<UncompiledT
>(source
));
146 void SetJSFunction(JSObject
* function
) {
147 wrapper().set(nsXBLMaybeCompiled
<UncompiledT
>(function
));
150 JS::Heap
<JSObject
*>& AsHeapObject()
152 MOZ_ASSERT(extract()->IsCompiled());
153 return *reinterpret_cast<JS::Heap
<JSObject
*>*>(this);
159 #endif // nsXBLMaybeCompiled_h__