Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set ts=8 sts=4 et sw=4 tw=99: */
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 : /* private inline methods (#include'd by xpcprivate.h). */
8 :
9 : #ifndef xpcinlines_h___
10 : #define xpcinlines_h___
11 :
12 : #include <algorithm>
13 :
14 : /***************************************************************************/
15 :
16 : inline void
17 2 : XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
18 : {
19 2 : variant->AddToRootSet(&mVariantRoots);
20 2 : }
21 :
22 : inline void
23 976 : XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
24 : {
25 976 : wrappedJS->AddToRootSet(&mWrappedJSRoots);
26 976 : }
27 :
28 : /***************************************************************************/
29 :
30 : inline bool
31 7890 : XPCCallContext::IsValid() const
32 : {
33 7890 : return mState != INIT_FAILED;
34 : }
35 :
36 : inline XPCJSContext*
37 87658 : XPCCallContext::GetContext() const
38 : {
39 87658 : CHECK_STATE(HAVE_CONTEXT);
40 87658 : return mXPCJSContext;
41 : }
42 :
43 : inline JSContext*
44 83268 : XPCCallContext::GetJSContext() const
45 : {
46 83268 : CHECK_STATE(HAVE_CONTEXT);
47 83268 : return mJSContext;
48 : }
49 :
50 : inline XPCCallContext*
51 0 : XPCCallContext::GetPrevCallContext() const
52 : {
53 0 : CHECK_STATE(HAVE_CONTEXT);
54 0 : return mPrevCallContext;
55 : }
56 :
57 : inline nsISupports*
58 : XPCCallContext::GetIdentityObject() const
59 : {
60 : CHECK_STATE(HAVE_OBJECT);
61 : if (mWrapper)
62 : return mWrapper->GetIdentityObject();
63 : return nullptr;
64 : }
65 :
66 : inline XPCWrappedNative*
67 36686 : XPCCallContext::GetWrapper() const
68 : {
69 36686 : if (mState == INIT_FAILED)
70 0 : return nullptr;
71 :
72 36686 : CHECK_STATE(HAVE_OBJECT);
73 36686 : return mWrapper;
74 : }
75 :
76 : inline XPCWrappedNativeProto*
77 : XPCCallContext::GetProto() const
78 : {
79 : CHECK_STATE(HAVE_OBJECT);
80 : return mWrapper ? mWrapper->GetProto() : nullptr;
81 : }
82 :
83 : inline bool
84 0 : XPCCallContext::CanGetTearOff() const
85 : {
86 0 : return mState >= HAVE_OBJECT;
87 : }
88 :
89 : inline XPCWrappedNativeTearOff*
90 12006 : XPCCallContext::GetTearOff() const
91 : {
92 12006 : CHECK_STATE(HAVE_OBJECT);
93 12006 : return mTearOff;
94 : }
95 :
96 : inline nsIXPCScriptable*
97 3232 : XPCCallContext::GetScriptable() const
98 : {
99 3232 : CHECK_STATE(HAVE_OBJECT);
100 3232 : return mScriptable;
101 : }
102 :
103 : inline bool
104 : XPCCallContext::CanGetSet() const
105 : {
106 : return mState >= HAVE_NAME;
107 : }
108 :
109 : inline XPCNativeSet*
110 2528 : XPCCallContext::GetSet() const
111 : {
112 2528 : CHECK_STATE(HAVE_NAME);
113 2528 : return mSet;
114 : }
115 :
116 : inline XPCNativeInterface*
117 16509 : XPCCallContext::GetInterface() const
118 : {
119 16509 : CHECK_STATE(HAVE_NAME);
120 16509 : return mInterface;
121 : }
122 :
123 : inline XPCNativeMember*
124 2830 : XPCCallContext::GetMember() const
125 : {
126 2830 : CHECK_STATE(HAVE_NAME);
127 2830 : return mMember;
128 : }
129 :
130 : inline bool
131 13976 : XPCCallContext::HasInterfaceAndMember() const
132 : {
133 13976 : return mState >= HAVE_NAME && mInterface && mMember;
134 : }
135 :
136 : inline jsid
137 : XPCCallContext::GetName() const
138 : {
139 : CHECK_STATE(HAVE_NAME);
140 : return mName;
141 : }
142 :
143 : inline bool
144 2465 : XPCCallContext::GetStaticMemberIsLocal() const
145 : {
146 2465 : CHECK_STATE(HAVE_NAME);
147 2465 : return mStaticMemberIsLocal;
148 : }
149 :
150 : inline unsigned
151 11996 : XPCCallContext::GetArgc() const
152 : {
153 11996 : CHECK_STATE(READY_TO_CALL);
154 11996 : return mArgc;
155 : }
156 :
157 : inline JS::Value*
158 11996 : XPCCallContext::GetArgv() const
159 : {
160 11996 : CHECK_STATE(READY_TO_CALL);
161 11996 : return mArgv;
162 : }
163 :
164 : inline JS::Value*
165 : XPCCallContext::GetRetVal() const
166 : {
167 : CHECK_STATE(READY_TO_CALL);
168 : return mRetVal;
169 : }
170 :
171 : inline void
172 20599 : XPCCallContext::SetRetVal(const JS::Value& val)
173 : {
174 20599 : CHECK_STATE(HAVE_ARGS);
175 20599 : if (mRetVal)
176 20599 : *mRetVal = val;
177 20599 : }
178 :
179 : inline jsid
180 2505 : XPCCallContext::GetResolveName() const
181 : {
182 2505 : CHECK_STATE(HAVE_CONTEXT);
183 2505 : return GetContext()->GetResolveName();
184 : }
185 :
186 : inline jsid
187 38660 : XPCCallContext::SetResolveName(JS::HandleId name)
188 : {
189 38660 : CHECK_STATE(HAVE_CONTEXT);
190 38660 : return GetContext()->SetResolveName(name);
191 : }
192 :
193 : inline XPCWrappedNative*
194 1408 : XPCCallContext::GetResolvingWrapper() const
195 : {
196 1408 : CHECK_STATE(HAVE_OBJECT);
197 1408 : return GetContext()->GetResolvingWrapper();
198 : }
199 :
200 : inline XPCWrappedNative*
201 6138 : XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
202 : {
203 6138 : CHECK_STATE(HAVE_OBJECT);
204 6138 : return GetContext()->SetResolvingWrapper(w);
205 : }
206 :
207 : inline uint16_t
208 11996 : XPCCallContext::GetMethodIndex() const
209 : {
210 11996 : CHECK_STATE(HAVE_OBJECT);
211 11996 : return mMethodIndex;
212 : }
213 :
214 : inline void
215 : XPCCallContext::SetMethodIndex(uint16_t index)
216 : {
217 : CHECK_STATE(HAVE_OBJECT);
218 : mMethodIndex = index;
219 : }
220 :
221 : /***************************************************************************/
222 : inline XPCNativeInterface*
223 14106 : XPCNativeMember::GetInterface() const
224 : {
225 : XPCNativeMember* arrayStart =
226 14106 : const_cast<XPCNativeMember*>(this - mIndexInInterface);
227 14106 : size_t arrayStartOffset = XPCNativeInterface::OffsetOfMembers();
228 : char* xpcNativeInterfaceStart =
229 14106 : reinterpret_cast<char*>(arrayStart) - arrayStartOffset;
230 14106 : return reinterpret_cast<XPCNativeInterface*>(xpcNativeInterfaceStart);
231 : }
232 :
233 : /***************************************************************************/
234 :
235 : inline const nsIID*
236 16972 : XPCNativeInterface::GetIID() const
237 : {
238 : const nsIID* iid;
239 16972 : return NS_SUCCEEDED(mInfo->GetIIDShared(&iid)) ? iid : nullptr;
240 : }
241 :
242 : inline const char*
243 1985 : XPCNativeInterface::GetNameString() const
244 : {
245 : const char* name;
246 1985 : return NS_SUCCEEDED(mInfo->GetNameShared(&name)) ? name : nullptr;
247 : }
248 :
249 : inline XPCNativeMember*
250 21495 : XPCNativeInterface::FindMember(jsid name) const
251 : {
252 21495 : const XPCNativeMember* member = mMembers;
253 134402 : for (int i = (int) mMemberCount; i > 0; i--, member++)
254 120584 : if (member->GetName() == name)
255 7677 : return const_cast<XPCNativeMember*>(member);
256 13818 : return nullptr;
257 : }
258 :
259 : inline bool
260 12 : XPCNativeInterface::HasAncestor(const nsIID* iid) const
261 : {
262 12 : bool found = false;
263 12 : mInfo->HasAncestor(iid, &found);
264 12 : return found;
265 : }
266 :
267 : /* static */
268 : inline size_t
269 14106 : XPCNativeInterface::OffsetOfMembers()
270 : {
271 14106 : return offsetof(XPCNativeInterface, mMembers);
272 : }
273 :
274 : /***************************************************************************/
275 :
276 235 : inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet,
277 235 : XPCNativeInterface* addition)
278 : : mBaseSet(baseSet)
279 235 : , mAddition(addition)
280 : {
281 235 : MOZ_ASSERT(mBaseSet);
282 235 : MOZ_ASSERT(mAddition);
283 235 : MOZ_ASSERT(!mBaseSet->HasInterface(mAddition));
284 235 : }
285 :
286 : /***************************************************************************/
287 :
288 : inline bool
289 10671 : XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
290 : uint16_t* pInterfaceIndex) const
291 : {
292 : XPCNativeInterface* const * iface;
293 10671 : int count = (int) mInterfaceCount;
294 : int i;
295 :
296 : // look for interface names first
297 :
298 32188 : for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
299 21517 : if (name == (*iface)->GetName()) {
300 0 : if (pMember)
301 0 : *pMember = nullptr;
302 0 : if (pInterfaceIndex)
303 0 : *pInterfaceIndex = (uint16_t) i;
304 0 : return true;
305 : }
306 : }
307 :
308 : // look for method names
309 22838 : for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
310 19694 : XPCNativeMember* member = (*iface)->FindMember(name);
311 19694 : if (member) {
312 7527 : if (pMember)
313 7443 : *pMember = member;
314 7527 : if (pInterfaceIndex)
315 7527 : *pInterfaceIndex = (uint16_t) i;
316 7527 : return true;
317 : }
318 : }
319 3144 : return false;
320 : }
321 :
322 : inline bool
323 10345 : XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
324 : RefPtr<XPCNativeInterface>* pInterface) const
325 : {
326 : uint16_t index;
327 10345 : if (!FindMember(name, pMember, &index))
328 2902 : return false;
329 7443 : *pInterface = mInterfaces[index];
330 7443 : return true;
331 : }
332 :
333 : inline bool
334 5067 : XPCNativeSet::FindMember(JS::HandleId name,
335 : XPCNativeMember** pMember,
336 : RefPtr<XPCNativeInterface>* pInterface,
337 : XPCNativeSet* protoSet,
338 : bool* pIsLocal) const
339 : {
340 : XPCNativeMember* Member;
341 10134 : RefPtr<XPCNativeInterface> Interface;
342 : XPCNativeMember* protoMember;
343 :
344 5067 : if (!FindMember(name, &Member, &Interface))
345 134 : return false;
346 :
347 4933 : *pMember = Member;
348 :
349 4933 : *pIsLocal =
350 9866 : !Member ||
351 10102 : !protoSet ||
352 261 : (protoSet != this &&
353 497 : !protoSet->MatchesSetUpToInterface(this, Interface) &&
354 236 : (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
355 0 : protoMember != Member));
356 :
357 4933 : *pInterface = Interface.forget();
358 :
359 4933 : return true;
360 : }
361 :
362 : inline XPCNativeInterface*
363 0 : XPCNativeSet::FindNamedInterface(jsid name) const
364 : {
365 0 : XPCNativeInterface* const * pp = mInterfaces;
366 :
367 0 : for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
368 0 : XPCNativeInterface* iface = *pp;
369 :
370 0 : if (name == iface->GetName())
371 0 : return iface;
372 : }
373 0 : return nullptr;
374 : }
375 :
376 : inline XPCNativeInterface*
377 2890 : XPCNativeSet::FindInterfaceWithIID(const nsIID& iid) const
378 : {
379 2890 : XPCNativeInterface* const * pp = mInterfaces;
380 :
381 5900 : for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
382 5864 : XPCNativeInterface* iface = *pp;
383 :
384 5864 : if (iface->GetIID()->Equals(iid))
385 2854 : return iface;
386 : }
387 36 : return nullptr;
388 : }
389 :
390 : inline bool
391 15421 : XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const
392 : {
393 15421 : XPCNativeInterface* const * pp = mInterfaces;
394 :
395 29794 : for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
396 28539 : if (aInterface == *pp)
397 14166 : return true;
398 : }
399 1255 : return false;
400 : }
401 :
402 : inline bool
403 3 : XPCNativeSet::HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const
404 : {
405 3 : return HasInterfaceWithAncestor(aInterface->GetIID());
406 : }
407 :
408 : inline bool
409 3 : XPCNativeSet::HasInterfaceWithAncestor(const nsIID* iid) const
410 : {
411 : // We can safely skip the first interface which is *always* nsISupports.
412 3 : XPCNativeInterface* const * pp = mInterfaces+1;
413 15 : for (int i = (int) mInterfaceCount; i > 1; i--, pp++)
414 12 : if ((*pp)->HasAncestor(iid))
415 0 : return true;
416 :
417 : // This is rare, so check last.
418 3 : if (iid == &NS_GET_IID(nsISupports))
419 0 : return true;
420 :
421 3 : return false;
422 : }
423 :
424 : inline bool
425 261 : XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
426 : XPCNativeInterface* iface) const
427 : {
428 261 : int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount));
429 :
430 261 : XPCNativeInterface* const * pp1 = mInterfaces;
431 261 : XPCNativeInterface* const * pp2 = other->mInterfaces;
432 :
433 531 : for (int i = (int) count; i > 0; i--, pp1++, pp2++) {
434 295 : XPCNativeInterface* cur = (*pp1);
435 295 : if (cur != (*pp2))
436 0 : return false;
437 295 : if (cur == iface)
438 25 : return true;
439 : }
440 236 : return false;
441 : }
442 :
443 : /***************************************************************************/
444 :
445 : inline
446 0 : JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
447 : {
448 0 : return mJSObject.unbarrieredGetPtr();
449 : }
450 :
451 : inline
452 0 : JSObject* XPCWrappedNativeTearOff::GetJSObject()
453 : {
454 0 : return mJSObject;
455 : }
456 :
457 : inline
458 0 : void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj)
459 : {
460 0 : MOZ_ASSERT(!IsMarked());
461 0 : mJSObject = JSObj;
462 0 : }
463 :
464 : inline
465 0 : void XPCWrappedNativeTearOff::JSObjectMoved(JSObject* obj, const JSObject* old)
466 : {
467 0 : MOZ_ASSERT(!IsMarked());
468 0 : MOZ_ASSERT(mJSObject == old);
469 0 : mJSObject = obj;
470 0 : }
471 :
472 : inline
473 0 : XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
474 : {
475 0 : MOZ_COUNT_DTOR(XPCWrappedNativeTearOff);
476 0 : MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()),
477 : "tearoff not empty in dtor");
478 0 : }
479 :
480 : /***************************************************************************/
481 :
482 : inline bool
483 2890 : XPCWrappedNative::HasInterfaceNoQI(const nsIID& iid)
484 : {
485 2890 : return nullptr != GetSet()->FindInterfaceWithIID(iid);
486 : }
487 :
488 : inline void
489 0 : XPCWrappedNative::SweepTearOffs()
490 : {
491 0 : for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; to = to->GetNextTearOff()) {
492 0 : bool marked = to->IsMarked();
493 0 : to->Unmark();
494 0 : if (marked)
495 0 : continue;
496 :
497 : // If this tearoff does not have a live dedicated JSObject,
498 : // then let's recycle it.
499 0 : if (!to->GetJSObjectPreserveColor()) {
500 0 : to->SetNative(nullptr);
501 0 : to->SetInterface(nullptr);
502 : }
503 : }
504 0 : }
505 :
506 : /***************************************************************************/
507 :
508 : inline bool
509 46 : xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, jsid idArg)
510 : {
511 92 : JS::RootedId id(cx, idArg);
512 : bool dummy;
513 92 : return JS_HasPropertyById(cx, obj, id, &dummy);
514 : }
515 :
516 : inline jsid
517 1001 : GetJSIDByIndex(JSContext* cx, unsigned index)
518 : {
519 1001 : XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance();
520 1001 : return xpcrt->GetStringID(index);
521 : }
522 :
523 : inline
524 0 : bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx)
525 : {
526 0 : XPCThrower::ThrowBadParam(rv, paramNum, ccx);
527 0 : return false;
528 : }
529 :
530 : inline
531 1978 : void ThrowBadResult(nsresult result, XPCCallContext& ccx)
532 : {
533 : XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE,
534 1978 : result, ccx);
535 1978 : }
536 :
537 : /***************************************************************************/
538 :
539 : #endif /* xpcinlines_h___ */
|