js/xpconnect/src/XPCInlines.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:1711f2fc95a0
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 XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
18 {
19 variant->AddToRootSet(&mVariantRoots);
20 }
21
22 inline void
23 XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
24 {
25 wrappedJS->AddToRootSet(&mWrappedJSRoots);
26 }
27
28 inline void
29 XPCJSRuntime::AddObjectHolderRoot(XPCJSObjectHolder* holder)
30 {
31 holder->AddToRootSet(&mObjectHolderRoots);
32 }
33
34 /***************************************************************************/
35
36 inline bool
37 XPCCallContext::IsValid() const
38 {
39 return mState != INIT_FAILED;
40 }
41
42 inline XPCJSRuntime*
43 XPCCallContext::GetRuntime() const
44 {
45 CHECK_STATE(HAVE_CONTEXT);
46 return mXPCContext->GetRuntime();
47 }
48
49 inline XPCContext*
50 XPCCallContext::GetXPCContext() const
51 {
52 CHECK_STATE(HAVE_CONTEXT);
53 return mXPCContext;
54 }
55
56 inline JSContext*
57 XPCCallContext::GetJSContext() const
58 {
59 CHECK_STATE(HAVE_CONTEXT);
60 return mJSContext;
61 }
62
63 inline XPCContext::LangType
64 XPCCallContext::GetCallerLanguage() const
65 {
66 CHECK_STATE(HAVE_CONTEXT);
67 return mCallerLanguage;
68 }
69
70 inline XPCContext::LangType
71 XPCCallContext::GetPrevCallerLanguage() const
72 {
73 CHECK_STATE(HAVE_CONTEXT);
74 return mPrevCallerLanguage;
75 }
76
77 inline XPCCallContext*
78 XPCCallContext::GetPrevCallContext() const
79 {
80 CHECK_STATE(HAVE_CONTEXT);
81 return mPrevCallContext;
82 }
83
84 inline JSObject*
85 XPCCallContext::GetFlattenedJSObject() const
86 {
87 CHECK_STATE(HAVE_OBJECT);
88 return mFlattenedJSObject;
89 }
90
91 inline nsISupports*
92 XPCCallContext::GetIdentityObject() const
93 {
94 CHECK_STATE(HAVE_OBJECT);
95 if (mWrapper)
96 return mWrapper->GetIdentityObject();
97 return mFlattenedJSObject ?
98 static_cast<nsISupports*>(xpc_GetJSPrivate(mFlattenedJSObject)) :
99 nullptr;
100 }
101
102 inline XPCWrappedNative*
103 XPCCallContext::GetWrapper() const
104 {
105 if (mState == INIT_FAILED)
106 return nullptr;
107
108 CHECK_STATE(HAVE_OBJECT);
109 return mWrapper;
110 }
111
112 inline XPCWrappedNativeProto*
113 XPCCallContext::GetProto() const
114 {
115 CHECK_STATE(HAVE_OBJECT);
116 return mWrapper ? mWrapper->GetProto() : nullptr;
117 }
118
119 inline bool
120 XPCCallContext::CanGetTearOff() const
121 {
122 return mState >= HAVE_OBJECT;
123 }
124
125 inline XPCWrappedNativeTearOff*
126 XPCCallContext::GetTearOff() const
127 {
128 CHECK_STATE(HAVE_OBJECT);
129 return mTearOff;
130 }
131
132 inline XPCNativeScriptableInfo*
133 XPCCallContext::GetScriptableInfo() const
134 {
135 CHECK_STATE(HAVE_OBJECT);
136 return mScriptableInfo;
137 }
138
139 inline bool
140 XPCCallContext::CanGetSet() const
141 {
142 return mState >= HAVE_NAME;
143 }
144
145 inline XPCNativeSet*
146 XPCCallContext::GetSet() const
147 {
148 CHECK_STATE(HAVE_NAME);
149 return mSet;
150 }
151
152 inline bool
153 XPCCallContext::CanGetInterface() const
154 {
155 return mState >= HAVE_NAME;
156 }
157
158 inline XPCNativeInterface*
159 XPCCallContext::GetInterface() const
160 {
161 CHECK_STATE(HAVE_NAME);
162 return mInterface;
163 }
164
165 inline XPCNativeMember*
166 XPCCallContext::GetMember() const
167 {
168 CHECK_STATE(HAVE_NAME);
169 return mMember;
170 }
171
172 inline bool
173 XPCCallContext::HasInterfaceAndMember() const
174 {
175 return mState >= HAVE_NAME && mInterface && mMember;
176 }
177
178 inline jsid
179 XPCCallContext::GetName() const
180 {
181 CHECK_STATE(HAVE_NAME);
182 return mName;
183 }
184
185 inline bool
186 XPCCallContext::GetStaticMemberIsLocal() const
187 {
188 CHECK_STATE(HAVE_NAME);
189 return mStaticMemberIsLocal;
190 }
191
192 inline unsigned
193 XPCCallContext::GetArgc() const
194 {
195 CHECK_STATE(READY_TO_CALL);
196 return mArgc;
197 }
198
199 inline jsval*
200 XPCCallContext::GetArgv() const
201 {
202 CHECK_STATE(READY_TO_CALL);
203 return mArgv;
204 }
205
206 inline jsval*
207 XPCCallContext::GetRetVal() const
208 {
209 CHECK_STATE(READY_TO_CALL);
210 return mRetVal;
211 }
212
213 inline void
214 XPCCallContext::SetRetVal(jsval val)
215 {
216 CHECK_STATE(HAVE_ARGS);
217 if (mRetVal)
218 *mRetVal = val;
219 }
220
221 inline jsid
222 XPCCallContext::GetResolveName() const
223 {
224 CHECK_STATE(HAVE_CONTEXT);
225 return XPCJSRuntime::Get()->GetResolveName();
226 }
227
228 inline jsid
229 XPCCallContext::SetResolveName(JS::HandleId name)
230 {
231 CHECK_STATE(HAVE_CONTEXT);
232 return XPCJSRuntime::Get()->SetResolveName(name);
233 }
234
235 inline XPCWrappedNative*
236 XPCCallContext::GetResolvingWrapper() const
237 {
238 CHECK_STATE(HAVE_OBJECT);
239 return XPCJSRuntime::Get()->GetResolvingWrapper();
240 }
241
242 inline XPCWrappedNative*
243 XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
244 {
245 CHECK_STATE(HAVE_OBJECT);
246 return XPCJSRuntime::Get()->SetResolvingWrapper(w);
247 }
248
249 inline uint16_t
250 XPCCallContext::GetMethodIndex() const
251 {
252 CHECK_STATE(HAVE_OBJECT);
253 return mMethodIndex;
254 }
255
256 inline void
257 XPCCallContext::SetMethodIndex(uint16_t index)
258 {
259 CHECK_STATE(HAVE_OBJECT);
260 mMethodIndex = index;
261 }
262
263 /***************************************************************************/
264
265 inline const nsIID*
266 XPCNativeInterface::GetIID() const
267 {
268 const nsIID* iid;
269 return NS_SUCCEEDED(mInfo->GetIIDShared(&iid)) ? iid : nullptr;
270 }
271
272 inline const char*
273 XPCNativeInterface::GetNameString() const
274 {
275 const char* name;
276 return NS_SUCCEEDED(mInfo->GetNameShared(&name)) ? name : nullptr;
277 }
278
279 inline XPCNativeMember*
280 XPCNativeInterface::FindMember(jsid name) const
281 {
282 const XPCNativeMember* member = mMembers;
283 for (int i = (int) mMemberCount; i > 0; i--, member++)
284 if (member->GetName() == name)
285 return const_cast<XPCNativeMember*>(member);
286 return nullptr;
287 }
288
289 inline bool
290 XPCNativeInterface::HasAncestor(const nsIID* iid) const
291 {
292 bool found = false;
293 mInfo->HasAncestor(iid, &found);
294 return found;
295 }
296
297 /***************************************************************************/
298
299 inline bool
300 XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
301 uint16_t* pInterfaceIndex) const
302 {
303 XPCNativeInterface* const * iface;
304 int count = (int) mInterfaceCount;
305 int i;
306
307 // look for interface names first
308
309 for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
310 if (name == (*iface)->GetName()) {
311 if (pMember)
312 *pMember = nullptr;
313 if (pInterfaceIndex)
314 *pInterfaceIndex = (uint16_t) i;
315 return true;
316 }
317 }
318
319 // look for method names
320 for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
321 XPCNativeMember* member = (*iface)->FindMember(name);
322 if (member) {
323 if (pMember)
324 *pMember = member;
325 if (pInterfaceIndex)
326 *pInterfaceIndex = (uint16_t) i;
327 return true;
328 }
329 }
330 return false;
331 }
332
333 inline bool
334 XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
335 XPCNativeInterface** pInterface) const
336 {
337 uint16_t index;
338 if (!FindMember(name, pMember, &index))
339 return false;
340 *pInterface = mInterfaces[index];
341 return true;
342 }
343
344 inline bool
345 XPCNativeSet::FindMember(jsid name,
346 XPCNativeMember** pMember,
347 XPCNativeInterface** pInterface,
348 XPCNativeSet* protoSet,
349 bool* pIsLocal) const
350 {
351 XPCNativeMember* Member;
352 XPCNativeInterface* Interface;
353 XPCNativeMember* protoMember;
354
355 if (!FindMember(name, &Member, &Interface))
356 return false;
357
358 *pMember = Member;
359 *pInterface = Interface;
360
361 *pIsLocal =
362 !Member ||
363 !protoSet ||
364 (protoSet != this &&
365 !protoSet->MatchesSetUpToInterface(this, Interface) &&
366 (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
367 protoMember != Member));
368
369 return true;
370 }
371
372 inline XPCNativeInterface*
373 XPCNativeSet::FindNamedInterface(jsid name) const
374 {
375 XPCNativeInterface* const * pp = mInterfaces;
376
377 for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
378 XPCNativeInterface* iface = *pp;
379
380 if (name == iface->GetName())
381 return iface;
382 }
383 return nullptr;
384 }
385
386 inline XPCNativeInterface*
387 XPCNativeSet::FindInterfaceWithIID(const nsIID& iid) const
388 {
389 XPCNativeInterface* const * pp = mInterfaces;
390
391 for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
392 XPCNativeInterface* iface = *pp;
393
394 if (iface->GetIID()->Equals(iid))
395 return iface;
396 }
397 return nullptr;
398 }
399
400 inline bool
401 XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const
402 {
403 XPCNativeInterface* const * pp = mInterfaces;
404
405 for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
406 if (aInterface == *pp)
407 return true;
408 }
409 return false;
410 }
411
412 inline bool
413 XPCNativeSet::HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const
414 {
415 return HasInterfaceWithAncestor(aInterface->GetIID());
416 }
417
418 inline bool
419 XPCNativeSet::HasInterfaceWithAncestor(const nsIID* iid) const
420 {
421 // We can safely skip the first interface which is *always* nsISupports.
422 XPCNativeInterface* const * pp = mInterfaces+1;
423 for (int i = (int) mInterfaceCount; i > 1; i--, pp++)
424 if ((*pp)->HasAncestor(iid))
425 return true;
426
427 // This is rare, so check last.
428 if (iid == &NS_GET_IID(nsISupports))
429 return true;
430
431 return false;
432 }
433
434 inline bool
435 XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
436 XPCNativeInterface* iface) const
437 {
438 int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount));
439
440 XPCNativeInterface* const * pp1 = mInterfaces;
441 XPCNativeInterface* const * pp2 = other->mInterfaces;
442
443 for (int i = (int) count; i > 0; i--, pp1++, pp2++) {
444 XPCNativeInterface* cur = (*pp1);
445 if (cur != (*pp2))
446 return false;
447 if (cur == iface)
448 return true;
449 }
450 return false;
451 }
452
453 inline void XPCNativeSet::Mark()
454 {
455 if (IsMarked())
456 return;
457
458 XPCNativeInterface* const * pp = mInterfaces;
459
460 for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
461 (*pp)->Mark();
462
463 MarkSelfOnly();
464 }
465
466 #ifdef DEBUG
467 inline void XPCNativeSet::ASSERT_NotMarked()
468 {
469 MOZ_ASSERT(!IsMarked(), "bad");
470
471 XPCNativeInterface* const * pp = mInterfaces;
472
473 for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
474 MOZ_ASSERT(!(*pp)->IsMarked(), "bad");
475 }
476 #endif
477
478 /***************************************************************************/
479
480 inline
481 JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
482 {
483 return reinterpret_cast<JSObject *>(reinterpret_cast<uintptr_t>(mJSObject) & ~1);
484 }
485
486 inline
487 JSObject* XPCWrappedNativeTearOff::GetJSObject()
488 {
489 JSObject *obj = GetJSObjectPreserveColor();
490 if (obj) {
491 JS::ExposeObjectToActiveJS(obj);
492 }
493 return obj;
494 }
495
496 inline
497 void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj)
498 {
499 MOZ_ASSERT(!IsMarked());
500 mJSObject = JSObj;
501 }
502
503 inline
504 XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
505 {
506 MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()),
507 "tearoff not empty in dtor");
508 }
509
510 /***************************************************************************/
511
512 inline bool
513 XPCWrappedNative::HasInterfaceNoQI(const nsIID& iid)
514 {
515 return nullptr != GetSet()->FindInterfaceWithIID(iid);
516 }
517
518 inline void
519 XPCWrappedNative::SweepTearOffs()
520 {
521 XPCWrappedNativeTearOffChunk* chunk;
522 for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
523 XPCWrappedNativeTearOff* to = chunk->mTearOffs;
524 for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK; i > 0; i--, to++) {
525 bool marked = to->IsMarked();
526 to->Unmark();
527 if (marked)
528 continue;
529
530 // If this tearoff does not have a live dedicated JSObject,
531 // then let's recycle it.
532 if (!to->GetJSObjectPreserveColor()) {
533 nsISupports* obj = to->GetNative();
534 if (obj) {
535 obj->Release();
536 to->SetNative(nullptr);
537 }
538 to->SetInterface(nullptr);
539 }
540 }
541 }
542 }
543
544 /***************************************************************************/
545
546 inline bool
547 xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, jsid idArg)
548 {
549 JS::RootedValue prop(cx);
550 JS::RootedId id(cx, idArg);
551
552 if (!JS_LookupPropertyById(cx, obj, id, &prop))
553 return false;
554 return true;
555 }
556
557 inline jsid
558 GetRTIdByIndex(JSContext *cx, unsigned index)
559 {
560 XPCJSRuntime *rt = nsXPConnect::XPConnect()->GetRuntime();
561 return rt->GetStringID(index);
562 }
563
564 inline
565 bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx)
566 {
567 XPCThrower::ThrowBadParam(rv, paramNum, ccx);
568 return false;
569 }
570
571 inline
572 void ThrowBadResult(nsresult result, XPCCallContext& ccx)
573 {
574 XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE,
575 result, ccx);
576 }
577
578 /***************************************************************************/
579
580 #endif /* xpcinlines_h___ */

mercurial