Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/xbl/nsXBLMaybeCompiled.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef nsXBLMaybeCompiled_h__
8
#define nsXBLMaybeCompiled_h__
9
10
#include "js/RootingAPI.h"
11
12
/*
13
 * A union containing either a pointer representing uncompiled source or a
14
 * JSObject* representing the compiled result.  The class is templated on the
15
 * source object type.
16
 *
17
 * The purpose of abstracting this as a separate class is to allow it to be
18
 * wrapped in a JS::Heap<T> to correctly handle post-barriering of the JSObject
19
 * pointer, when present.
20
 *
21
 * No implementation of rootKind() is provided, which prevents
22
 * Root<nsXBLMaybeCompiled<UncompiledT>> from being used.
23
 */
24
template <class UncompiledT>
25
class nsXBLMaybeCompiled
26
{
27
public:
28
0
  nsXBLMaybeCompiled() : mUncompiled(BIT_UNCOMPILED) {}
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::nsXBLMaybeCompiled()
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::nsXBLMaybeCompiled()
29
30
  explicit nsXBLMaybeCompiled(UncompiledT* uncompiled)
31
0
    : mUncompiled(reinterpret_cast<uintptr_t>(uncompiled) | BIT_UNCOMPILED) {}
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::nsXBLMaybeCompiled(nsXBLUncompiledMethod*)
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::nsXBLMaybeCompiled(nsXBLTextWithLineNumber*)
32
33
0
  explicit nsXBLMaybeCompiled(JSObject* compiled) : mCompiled(compiled) {}
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::nsXBLMaybeCompiled(JSObject*)
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::nsXBLMaybeCompiled(JSObject*)
34
35
  bool IsCompiled() const
36
0
  {
37
0
    return !(mUncompiled & BIT_UNCOMPILED);
38
0
  }
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::IsCompiled() const
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::IsCompiled() const
39
40
  UncompiledT* GetUncompiled() const
41
0
  {
42
0
    MOZ_ASSERT(!IsCompiled(), "Attempt to get compiled function as uncompiled");
43
0
    uintptr_t unmasked = mUncompiled & ~BIT_UNCOMPILED;
44
0
    return reinterpret_cast<UncompiledT*>(unmasked);
45
0
  }
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::GetUncompiled() const
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::GetUncompiled() const
46
47
  JSObject* GetJSFunction() const
48
0
  {
49
0
    MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
50
0
    if (mCompiled) {
51
0
      JS::ExposeObjectToActiveJS(mCompiled);
52
0
    }
53
0
    return mCompiled;
54
0
  }
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::GetJSFunction() const
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::GetJSFunction() const
55
56
  // This is appropriate for use in tracing methods, etc.
57
  JSObject* GetJSFunctionPreserveColor() const
58
0
  {
59
0
    MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
60
0
    return mCompiled;
61
0
  }
62
63
private:
64
  JSObject*& UnsafeGetJSFunction()
65
0
  {
66
0
    MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
67
0
    return mCompiled;
68
0
  }
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLUncompiledMethod>::UnsafeGetJSFunction()
Unexecuted instantiation: nsXBLMaybeCompiled<nsXBLTextWithLineNumber>::UnsafeGetJSFunction()
69
70
  enum { BIT_UNCOMPILED = 1 << 0 };
71
72
  union
73
  {
74
    // An pointer that represents the function before being compiled, with
75
    // BIT_UNCOMPILED set.
76
    uintptr_t mUncompiled;
77
78
    // The JS object for the compiled result.
79
    JSObject* mCompiled;
80
  };
81
82
  friend struct js::BarrierMethods<nsXBLMaybeCompiled<UncompiledT>>;
83
};
84
85
/* Add support for JS::Heap<nsXBLMaybeCompiled>. */
86
namespace JS {
87
88
template <class UncompiledT>
89
struct GCPolicy<nsXBLMaybeCompiled<UncompiledT>>
90
{
91
  static nsXBLMaybeCompiled<UncompiledT> initial() { return nsXBLMaybeCompiled<UncompiledT>(); }
92
};
93
94
} // namespace JS
95
96
namespace js {
97
98
template <class UncompiledT>
99
struct BarrierMethods<nsXBLMaybeCompiled<UncompiledT>>
100
{
101
  typedef struct BarrierMethods<JSObject *> Base;
102
103
  static void postBarrier(nsXBLMaybeCompiled<UncompiledT>* functionp,
104
                          nsXBLMaybeCompiled<UncompiledT> prev,
105
                          nsXBLMaybeCompiled<UncompiledT> next)
106
0
  {
107
0
    if (next.IsCompiled()) {
108
0
      Base::postBarrier(&functionp->UnsafeGetJSFunction(),
109
0
                        prev.IsCompiled() ? prev.UnsafeGetJSFunction() : nullptr,
110
0
                        next.UnsafeGetJSFunction());
111
0
    } else if (prev.IsCompiled()) {
112
0
      Base::postBarrier(&prev.UnsafeGetJSFunction(),
113
0
                        prev.UnsafeGetJSFunction(),
114
0
                        nullptr);
115
0
    }
116
0
  }
Unexecuted instantiation: js::BarrierMethods<nsXBLMaybeCompiled<nsXBLUncompiledMethod> >::postBarrier(nsXBLMaybeCompiled<nsXBLUncompiledMethod>*, nsXBLMaybeCompiled<nsXBLUncompiledMethod>, nsXBLMaybeCompiled<nsXBLUncompiledMethod>)
Unexecuted instantiation: js::BarrierMethods<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> >::postBarrier(nsXBLMaybeCompiled<nsXBLTextWithLineNumber>*, nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, nsXBLMaybeCompiled<nsXBLTextWithLineNumber>)
117
  static void exposeToJS(nsXBLMaybeCompiled<UncompiledT> fun) {
118
    if (fun.IsCompiled()) {
119
      JS::ExposeObjectToActiveJS(fun.UnsafeGetJSFunction());
120
    }
121
  }
122
};
123
124
template <class T>
125
struct IsHeapConstructibleType<nsXBLMaybeCompiled<T>>
126
{ // Yes, this is the exception to the rule. Sorry.
127
  static constexpr bool value = true;
128
};
129
130
template <class UncompiledT, class Wrapper>
131
class HeapBase<nsXBLMaybeCompiled<UncompiledT>, Wrapper>
132
{
133
0
  const Wrapper& wrapper() const {
134
0
    return *static_cast<const Wrapper*>(this);
135
0
  }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::wrapper() const
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::wrapper() const
136
137
0
  Wrapper& wrapper() {
138
0
    return *static_cast<Wrapper*>(this);
139
0
  }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::wrapper()
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::wrapper()
140
141
0
  const nsXBLMaybeCompiled<UncompiledT>* extract() const {
142
0
    return wrapper().address();
143
0
  }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::extract() const
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::extract() const
144
145
  nsXBLMaybeCompiled<UncompiledT>* extract() {
146
    return wrapper().unsafeGet();
147
  }
148
149
public:
150
0
  bool IsCompiled() const { return extract()->IsCompiled(); }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::IsCompiled() const
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::IsCompiled() const
151
0
  UncompiledT* GetUncompiled() const { return extract()->GetUncompiled(); }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::GetUncompiled() const
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::GetUncompiled() const
152
0
  JSObject* GetJSFunction() const { return extract()->GetJSFunction(); }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::GetJSFunction() const
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::GetJSFunction() const
153
0
  JSObject* GetJSFunctionPreserveColor() const { return extract()->GetJSFunctionPreserveColor(); }
154
155
0
  void SetUncompiled(UncompiledT* source) {
156
0
    wrapper() = nsXBLMaybeCompiled<UncompiledT>(source);
157
0
  }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::SetUncompiled(nsXBLUncompiledMethod*)
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::SetUncompiled(nsXBLTextWithLineNumber*)
158
159
0
  void SetJSFunction(JSObject* function) {
160
0
    wrapper() = nsXBLMaybeCompiled<UncompiledT>(function);
161
0
  }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::SetJSFunction(JSObject*)
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::SetJSFunction(JSObject*)
162
163
  JS::Heap<JSObject*>& AsHeapObject()
164
0
  {
165
0
    MOZ_ASSERT(extract()->IsCompiled());
166
0
    return *reinterpret_cast<JS::Heap<JSObject*>*>(this);
167
0
  }
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLUncompiledMethod>, JS::Heap<nsXBLMaybeCompiled<nsXBLUncompiledMethod> > >::AsHeapObject()
Unexecuted instantiation: js::HeapBase<nsXBLMaybeCompiled<nsXBLTextWithLineNumber>, JS::Heap<nsXBLMaybeCompiled<nsXBLTextWithLineNumber> > >::AsHeapObject()
168
};
169
170
} /* namespace js */
171
172
#endif // nsXBLMaybeCompiled_h__