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 static void postBarrier(nsXBLMaybeCompiled
<UncompiledT
>* functionp
)
106 Base::postBarrier(&functionp
->UnsafeGetJSFunction());
109 static void relocate(nsXBLMaybeCompiled
<UncompiledT
>* functionp
)
111 Base::relocate(&functionp
->UnsafeGetJSFunction());
115 template <class UncompiledT
>
116 class HeapBase
<nsXBLMaybeCompiled
<UncompiledT
> >
118 const JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >& wrapper() const {
119 return *static_cast<const JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >*>(this);
122 JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >& wrapper() {
123 return *static_cast<JS::Heap
<nsXBLMaybeCompiled
<UncompiledT
> >*>(this);
126 const nsXBLMaybeCompiled
<UncompiledT
>* extract() const {
127 return wrapper().address();
130 nsXBLMaybeCompiled
<UncompiledT
>* extract() {
131 return wrapper().unsafeGet();
135 bool IsCompiled() const { return extract()->IsCompiled(); }
136 UncompiledT
* GetUncompiled() const { return extract()->GetUncompiled(); }
137 JSObject
* GetJSFunction() const { return extract()->GetJSFunction(); }
138 JSObject
* GetJSFunctionPreserveColor() const { return extract()->GetJSFunctionPreserveColor(); }
140 void SetUncompiled(UncompiledT
* source
) {
141 wrapper().set(nsXBLMaybeCompiled
<UncompiledT
>(source
));
144 void SetJSFunction(JSObject
* function
) {
145 wrapper().set(nsXBLMaybeCompiled
<UncompiledT
>(function
));
148 JS::Heap
<JSObject
*>& AsHeapObject()
150 MOZ_ASSERT(extract()->IsCompiled());
151 return *reinterpret_cast<JS::Heap
<JSObject
*>*>(this);
157 #endif // nsXBLMaybeCompiled_h__