Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=2 et :
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 dom_plugins_PluginScriptableObjectUtils_h
8 : #define dom_plugins_PluginScriptableObjectUtils_h
9 :
10 : #include "PluginModuleParent.h"
11 : #include "PluginModuleChild.h"
12 : #include "PluginInstanceParent.h"
13 : #include "PluginInstanceChild.h"
14 : #include "PluginScriptableObjectParent.h"
15 : #include "PluginScriptableObjectChild.h"
16 :
17 : #include "npapi.h"
18 : #include "npfunctions.h"
19 : #include "npruntime.h"
20 :
21 : #include "nsDebug.h"
22 :
23 : namespace mozilla {
24 : namespace plugins {
25 :
26 : inline PluginInstanceParent*
27 0 : GetInstance(NPObject* aObject)
28 : {
29 0 : NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
30 : "Bad class!");
31 :
32 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
33 0 : if (object->invalidated) {
34 0 : NS_WARNING("Calling method on an invalidated object!");
35 0 : return nullptr;
36 : }
37 0 : if (!object->parent) {
38 0 : return nullptr;
39 : }
40 0 : return object->parent->GetInstance();
41 : }
42 :
43 : inline NPObject*
44 0 : NPObjectFromVariant(const Variant& aRemoteVariant)
45 : {
46 0 : switch (aRemoteVariant.type()) {
47 : case Variant::TPPluginScriptableObjectParent: {
48 : PluginScriptableObjectParent* actor =
49 : const_cast<PluginScriptableObjectParent*>(
50 : reinterpret_cast<const PluginScriptableObjectParent*>(
51 0 : aRemoteVariant.get_PPluginScriptableObjectParent()));
52 0 : return actor->GetObject(true);
53 : }
54 :
55 : case Variant::TPPluginScriptableObjectChild: {
56 : PluginScriptableObjectChild* actor =
57 : const_cast<PluginScriptableObjectChild*>(
58 : reinterpret_cast<const PluginScriptableObjectChild*>(
59 0 : aRemoteVariant.get_PPluginScriptableObjectChild()));
60 0 : return actor->GetObject(true);
61 : }
62 :
63 : default:
64 0 : NS_NOTREACHED("Shouldn't get here!");
65 0 : return nullptr;
66 : }
67 : }
68 :
69 : inline NPObject*
70 : NPObjectFromVariant(const NPVariant& aVariant)
71 : {
72 : NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
73 : return NPVARIANT_TO_OBJECT(aVariant);
74 : }
75 :
76 : inline const NPNetscapeFuncs*
77 0 : GetNetscapeFuncs(PluginInstanceParent* aInstance)
78 : {
79 0 : PluginModuleParent* module = aInstance->Module();
80 0 : if (!module) {
81 0 : NS_WARNING("Null module?!");
82 0 : return nullptr;
83 : }
84 0 : return module->GetNetscapeFuncs();
85 : }
86 :
87 : inline const NPNetscapeFuncs*
88 0 : GetNetscapeFuncs(NPObject* aObject)
89 : {
90 0 : NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
91 : "Bad class!");
92 :
93 0 : PluginInstanceParent* instance = GetInstance(aObject);
94 0 : if (!instance) {
95 0 : return nullptr;
96 : }
97 :
98 0 : return GetNetscapeFuncs(instance);
99 : }
100 :
101 : inline void
102 0 : ReleaseRemoteVariant(Variant& aVariant)
103 : {
104 0 : switch (aVariant.type()) {
105 : case Variant::TPPluginScriptableObjectParent: {
106 : PluginScriptableObjectParent* actor =
107 : const_cast<PluginScriptableObjectParent*>(
108 : reinterpret_cast<const PluginScriptableObjectParent*>(
109 0 : aVariant.get_PPluginScriptableObjectParent()));
110 0 : actor->Unprotect();
111 0 : break;
112 : }
113 :
114 : case Variant::TPPluginScriptableObjectChild: {
115 0 : NS_ASSERTION(XRE_GetProcessType() == GeckoProcessType_Plugin,
116 : "Should only be running in the child!");
117 : PluginScriptableObjectChild* actor =
118 : const_cast<PluginScriptableObjectChild*>(
119 : reinterpret_cast<const PluginScriptableObjectChild*>(
120 0 : aVariant.get_PPluginScriptableObjectChild()));
121 0 : actor->Unprotect();
122 0 : break;
123 : }
124 :
125 : default:
126 0 : break; // Intentional fall-through for other variant types.
127 : }
128 :
129 0 : aVariant = mozilla::void_t();
130 0 : }
131 :
132 : bool
133 : ConvertToVariant(const Variant& aRemoteVariant,
134 : NPVariant& aVariant,
135 : PluginInstanceParent* aInstance = nullptr);
136 :
137 : template <class InstanceType>
138 : bool
139 : ConvertToRemoteVariant(const NPVariant& aVariant,
140 : Variant& aRemoteVariant,
141 : InstanceType* aInstance,
142 : bool aProtectActors = false);
143 :
144 : class ProtectedVariant
145 : {
146 : public:
147 0 : ProtectedVariant(const NPVariant& aVariant,
148 : PluginInstanceParent* aInstance)
149 0 : {
150 0 : mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
151 0 : }
152 :
153 0 : ProtectedVariant(const NPVariant& aVariant,
154 : PluginInstanceChild* aInstance)
155 0 : {
156 0 : mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
157 0 : }
158 :
159 0 : ~ProtectedVariant() {
160 0 : ReleaseRemoteVariant(mVariant);
161 0 : }
162 :
163 0 : bool IsOk() {
164 0 : return mOk;
165 : }
166 :
167 0 : operator const Variant&() {
168 0 : return mVariant;
169 : }
170 :
171 : private:
172 : Variant mVariant;
173 : bool mOk;
174 : };
175 :
176 : class ProtectedVariantArray
177 : {
178 : public:
179 0 : ProtectedVariantArray(const NPVariant* aArgs,
180 : uint32_t aCount,
181 : PluginInstanceParent* aInstance)
182 0 : : mUsingShadowArray(false)
183 : {
184 0 : for (uint32_t index = 0; index < aCount; index++) {
185 0 : Variant* remoteVariant = mArray.AppendElement();
186 0 : if (!(remoteVariant &&
187 0 : ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
188 : true))) {
189 0 : mOk = false;
190 0 : return;
191 : }
192 : }
193 0 : mOk = true;
194 : }
195 :
196 0 : ProtectedVariantArray(const NPVariant* aArgs,
197 : uint32_t aCount,
198 : PluginInstanceChild* aInstance)
199 0 : : mUsingShadowArray(false)
200 : {
201 0 : for (uint32_t index = 0; index < aCount; index++) {
202 0 : Variant* remoteVariant = mArray.AppendElement();
203 0 : if (!(remoteVariant &&
204 0 : ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
205 : true))) {
206 0 : mOk = false;
207 0 : return;
208 : }
209 : }
210 0 : mOk = true;
211 : }
212 :
213 0 : ~ProtectedVariantArray()
214 0 : {
215 0 : InfallibleTArray<Variant>& vars = EnsureAndGetShadowArray();
216 0 : uint32_t count = vars.Length();
217 0 : for (uint32_t index = 0; index < count; index++) {
218 0 : ReleaseRemoteVariant(vars[index]);
219 : }
220 0 : }
221 :
222 0 : operator const InfallibleTArray<Variant>&()
223 : {
224 0 : return EnsureAndGetShadowArray();
225 : }
226 :
227 0 : bool IsOk()
228 : {
229 0 : return mOk;
230 : }
231 :
232 : private:
233 : InfallibleTArray<Variant>&
234 0 : EnsureAndGetShadowArray()
235 : {
236 0 : if (!mUsingShadowArray) {
237 0 : mShadowArray.SwapElements(mArray);
238 0 : mUsingShadowArray = true;
239 : }
240 0 : return mShadowArray;
241 : }
242 :
243 : // We convert the variants fallibly, but pass them to Call*()
244 : // methods as an infallible array
245 : nsTArray<Variant> mArray;
246 : InfallibleTArray<Variant> mShadowArray;
247 : bool mOk;
248 : bool mUsingShadowArray;
249 : };
250 :
251 : template<class ActorType>
252 : struct ProtectedActorTraits
253 : {
254 : static bool Nullable();
255 : };
256 :
257 : template<class ActorType, class Traits=ProtectedActorTraits<ActorType> >
258 : class ProtectedActor
259 : {
260 : public:
261 0 : explicit ProtectedActor(ActorType* aActor) : mActor(aActor)
262 : {
263 0 : if (!Traits::Nullable()) {
264 0 : NS_ASSERTION(mActor, "This should never be null!");
265 : }
266 0 : }
267 :
268 0 : ~ProtectedActor()
269 : {
270 0 : if (Traits::Nullable() && !mActor)
271 0 : return;
272 0 : mActor->Unprotect();
273 0 : }
274 :
275 0 : ActorType* operator->()
276 : {
277 0 : return mActor;
278 : }
279 :
280 0 : explicit operator bool()
281 : {
282 0 : return !!mActor;
283 : }
284 :
285 : private:
286 : ActorType* mActor;
287 : };
288 :
289 : template<>
290 : struct ProtectedActorTraits<PluginScriptableObjectParent>
291 : {
292 0 : static bool Nullable() { return true; }
293 : };
294 :
295 : template<>
296 : struct ProtectedActorTraits<PluginScriptableObjectChild>
297 : {
298 0 : static bool Nullable() { return false; }
299 : };
300 :
301 : } /* namespace plugins */
302 : } /* namespace mozilla */
303 :
304 : #include "PluginScriptableObjectUtils-inl.h"
305 :
306 : #endif /* dom_plugins_PluginScriptableObjectUtils_h */
|