LCOV - code coverage report
Current view: directory - js/xpconnect/src - XPCCallContext.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 215 168 78.1 %
Date: 2012-06-02 Functions: 23 16 69.6 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  *
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla Communicator client code, released
      17                 :  * March 31, 1998.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  * Netscape Communications Corporation.
      21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *   John Bandhauer <jband@netscape.com> (original author)
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : /* Call context. */
      42                 : 
      43                 : #include "mozilla/Util.h"
      44                 : 
      45                 : #include "xpcprivate.h"
      46                 : 
      47                 : using namespace mozilla;
      48                 : 
      49        15741753 : XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
      50                 :                                JSContext* cx    /* = nsnull    */,
      51                 :                                JSObject* obj    /* = nsnull    */,
      52                 :                                JSObject* funobj /* = nsnull    */,
      53                 :                                jsid name        /* = JSID_VOID */,
      54                 :                                unsigned argc       /* = NO_ARGS   */,
      55                 :                                jsval *argv      /* = nsnull    */,
      56                 :                                jsval *rval      /* = nsnull    */)
      57                 :     :   mState(INIT_FAILED),
      58        15741753 :         mXPC(nsXPConnect::GetXPConnect()),
      59                 :         mThreadData(nsnull),
      60                 :         mXPCContext(nsnull),
      61                 :         mJSContext(cx),
      62                 :         mContextPopRequired(false),
      63                 :         mDestroyJSContextInDestructor(false),
      64        31483506 :         mCallerLanguage(callerLanguage)
      65                 : {
      66                 :     Init(callerLanguage, callerLanguage == NATIVE_CALLER, obj, funobj,
      67        15741753 :          INIT_SHOULD_LOOKUP_WRAPPER, name, argc, argv, rval);
      68        15741753 : }
      69                 : 
      70          132930 : XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
      71                 :                                JSContext* cx,
      72                 :                                JSBool callBeginRequest,
      73                 :                                JSObject* obj,
      74                 :                                JSObject* flattenedJSObject,
      75                 :                                XPCWrappedNative* wrapper,
      76                 :                                XPCWrappedNativeTearOff* tearOff)
      77                 :     :   mState(INIT_FAILED),
      78          132930 :         mXPC(nsXPConnect::GetXPConnect()),
      79                 :         mThreadData(nsnull),
      80                 :         mXPCContext(nsnull),
      81                 :         mJSContext(cx),
      82                 :         mContextPopRequired(false),
      83                 :         mDestroyJSContextInDestructor(false),
      84                 :         mCallerLanguage(callerLanguage),
      85                 :         mFlattenedJSObject(flattenedJSObject),
      86                 :         mWrapper(wrapper),
      87          265860 :         mTearOff(tearOff)
      88                 : {
      89                 :     Init(callerLanguage, callBeginRequest, obj, nsnull,
      90                 :          WRAPPER_PASSED_TO_CONSTRUCTOR, JSID_VOID, NO_ARGS,
      91          132930 :          nsnull, nsnull);
      92          132930 : }
      93                 : 
      94                 : void
      95        15874683 : XPCCallContext::Init(XPCContext::LangType callerLanguage,
      96                 :                      JSBool callBeginRequest,
      97                 :                      JSObject* obj,
      98                 :                      JSObject* funobj,
      99                 :                      WrapperInitOptions wrapperInitOptions,
     100                 :                      jsid name,
     101                 :                      unsigned argc,
     102                 :                      jsval *argv,
     103                 :                      jsval *rval)
     104                 : {
     105        15874683 :     if (!mXPC)
     106               0 :         return;
     107                 : 
     108        15874683 :     mThreadData = XPCPerThreadData::GetData(mJSContext);
     109                 : 
     110        15874683 :     if (!mThreadData)
     111               0 :         return;
     112                 : 
     113        15874683 :     XPCJSContextStack* stack = mThreadData->GetJSContextStack();
     114                 : 
     115        15874683 :     if (!stack) {
     116                 :         // If we don't have a stack we're probably in shutdown.
     117               0 :         mJSContext = nsnull;
     118               0 :         return;
     119                 :     }
     120                 : 
     121        15874683 :     JSContext *topJSContext = stack->Peek();
     122                 : 
     123        15874683 :     if (!mJSContext) {
     124                 :         // This is slightly questionable. If called without an explicit
     125                 :         // JSContext (generally a call to a wrappedJS) we will use the JSContext
     126                 :         // on the top of the JSContext stack - if there is one - *before*
     127                 :         // falling back on the safe JSContext.
     128                 :         // This is good AND bad because it makes calls from JS -> native -> JS
     129                 :         // have JS stack 'continuity' for purposes of stack traces etc.
     130                 :         // Note: this *is* what the pre-XPCCallContext xpconnect did too.
     131                 : 
     132         1851562 :         if (topJSContext) {
     133         1755364 :             mJSContext = topJSContext;
     134                 :         } else {
     135           96198 :             mJSContext = stack->GetSafeJSContext();
     136           96198 :             if (!mJSContext)
     137               0 :                 return;
     138                 :         }
     139                 :     }
     140                 : 
     141        15874683 :     if (topJSContext != mJSContext) {
     142          195436 :         if (!stack->Push(mJSContext)) {
     143               0 :             NS_ERROR("bad!");
     144               0 :             return;
     145                 :         }
     146          195436 :         mContextPopRequired = true;
     147                 :     }
     148                 : 
     149                 :     // Get into the request as early as we can to avoid problems with scanning
     150                 :     // callcontexts on other threads from within the gc callbacks.
     151                 : 
     152        15874683 :     NS_ASSERTION(!callBeginRequest || mCallerLanguage == NATIVE_CALLER,
     153                 :                  "Don't call JS_BeginRequest unless the caller is native.");
     154        15874683 :     if (callBeginRequest)
     155         2539405 :         JS_BeginRequest(mJSContext);
     156                 : 
     157        15874683 :     mXPCContext = XPCContext::GetXPCContext(mJSContext);
     158        15874683 :     mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage);
     159                 : 
     160                 :     // hook into call context chain for our thread
     161        15874683 :     mPrevCallContext = mThreadData->SetCallContext(this);
     162                 : 
     163                 :     // We only need to addref xpconnect once so only do it if this is the first
     164                 :     // context in the chain.
     165        15874683 :     if (!mPrevCallContext)
     166         4278171 :         NS_ADDREF(mXPC);
     167                 : 
     168        15874683 :     mState = HAVE_CONTEXT;
     169                 : 
     170        15874683 :     if (!obj)
     171         3911940 :         return;
     172                 : 
     173        11962743 :     mScopeForNewJSObjects = obj;
     174                 : 
     175        11962743 :     mState = HAVE_SCOPE;
     176                 : 
     177        11962743 :     mMethodIndex = 0xDEAD;
     178                 : 
     179        11962743 :     mState = HAVE_OBJECT;
     180                 : 
     181        11962743 :     mTearOff = nsnull;
     182        11962743 :     if (wrapperInitOptions == INIT_SHOULD_LOOKUP_WRAPPER) {
     183                 :         mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj,
     184                 :                                                                 funobj,
     185                 :                                                                 &mFlattenedJSObject,
     186        11829813 :                                                                 &mTearOff);
     187        11829813 :         if (mWrapper) {
     188        11829813 :             DEBUG_CheckWrapperThreadSafety(mWrapper);
     189                 : 
     190        11829813 :             mFlattenedJSObject = mWrapper->GetFlatJSObject();
     191                 : 
     192        11829813 :             if (mTearOff)
     193             248 :                 mScriptableInfo = nsnull;
     194                 :             else
     195        11829565 :                 mScriptableInfo = mWrapper->GetScriptableInfo();
     196                 :         } else {
     197               0 :             NS_ABORT_IF_FALSE(!mFlattenedJSObject || IS_SLIM_WRAPPER(mFlattenedJSObject),
     198                 :                               "should have a slim wrapper");
     199                 :         }
     200                 :     }
     201                 : 
     202        11962743 :     if (!JSID_IS_VOID(name))
     203         3236236 :         SetName(name);
     204                 : 
     205        11962743 :     if (argc != NO_ARGS)
     206         4420250 :         SetArgsAndResultPtr(argc, argv, rval);
     207                 : 
     208        11962743 :     CHECK_STATE(HAVE_OBJECT);
     209                 : }
     210                 : 
     211                 : void
     212         3285355 : XPCCallContext::SetName(jsid name)
     213                 : {
     214         3285355 :     CHECK_STATE(HAVE_OBJECT);
     215                 : 
     216         3285355 :     mName = name;
     217                 : 
     218         3285355 :     if (mTearOff) {
     219              79 :         mSet = nsnull;
     220              79 :         mInterface = mTearOff->GetInterface();
     221              79 :         mMember = mInterface->FindMember(name);
     222              79 :         mStaticMemberIsLocal = true;
     223              79 :         if (mMember && !mMember->IsConstant())
     224              79 :             mMethodIndex = mMember->GetIndex();
     225                 :     } else {
     226         3285276 :         mSet = mWrapper ? mWrapper->GetSet() : nsnull;
     227                 : 
     228         6570552 :         if (mSet &&
     229                 :             mSet->FindMember(name, &mMember, &mInterface,
     230         3285276 :                              mWrapper->HasProto() ?
     231          246848 :                              mWrapper->GetProto()->GetSet() :
     232                 :                              nsnull,
     233         6817400 :                              &mStaticMemberIsLocal)) {
     234         3254076 :             if (mMember && !mMember->IsConstant())
     235         3241465 :                 mMethodIndex = mMember->GetIndex();
     236                 :         } else {
     237           31200 :             mMember = nsnull;
     238           31200 :             mInterface = nsnull;
     239           31200 :             mStaticMemberIsLocal = false;
     240                 :         }
     241                 :     }
     242                 : 
     243         3285355 :     mState = HAVE_NAME;
     244         3285355 : }
     245                 : 
     246                 : void
     247         6731668 : XPCCallContext::SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member,
     248                 :                             JSBool isSetter)
     249                 : {
     250         6731668 :     CHECK_STATE(HAVE_CONTEXT);
     251                 : 
     252                 :     // We are going straight to the method info and need not do a lookup
     253                 :     // by id.
     254                 : 
     255                 :     // don't be tricked if method is called with wrong 'this'
     256         6731668 :     if (mTearOff && mTearOff->GetInterface() != iface)
     257               0 :         mTearOff = nsnull;
     258                 : 
     259         6731668 :     mSet = nsnull;
     260         6731668 :     mInterface = iface;
     261         6731668 :     mMember = member;
     262         6731668 :     mMethodIndex = mMember->GetIndex() + (isSetter ? 1 : 0);
     263         6731668 :     mName = mMember->GetName();
     264                 : 
     265         6731668 :     if (mState < HAVE_NAME)
     266            9898 :         mState = HAVE_NAME;
     267         6731668 : }
     268                 : 
     269                 : void
     270         6826808 : XPCCallContext::SetArgsAndResultPtr(unsigned argc,
     271                 :                                     jsval *argv,
     272                 :                                     jsval *rval)
     273                 : {
     274         6826808 :     CHECK_STATE(HAVE_OBJECT);
     275                 : 
     276         6826808 :     if (mState < HAVE_NAME) {
     277         6777689 :         mSet = nsnull;
     278         6777689 :         mInterface = nsnull;
     279         6777689 :         mMember = nsnull;
     280         6777689 :         mStaticMemberIsLocal = false;
     281                 :     }
     282                 : 
     283         6826808 :     mArgc   = argc;
     284         6826808 :     mArgv   = argv;
     285         6826808 :     mRetVal = rval;
     286                 : 
     287         6826808 :     mState = HAVE_ARGS;
     288         6826808 : }
     289                 : 
     290                 : nsresult
     291         6752344 : XPCCallContext::CanCallNow()
     292                 : {
     293                 :     nsresult rv;
     294                 : 
     295         6752344 :     if (!HasInterfaceAndMember())
     296               0 :         return NS_ERROR_UNEXPECTED;
     297         6752344 :     if (mState < HAVE_ARGS)
     298               0 :         return NS_ERROR_UNEXPECTED;
     299                 : 
     300         6752344 :     if (!mTearOff) {
     301         6752254 :         mTearOff = mWrapper->FindTearOff(*this, mInterface, false, &rv);
     302         6752254 :         if (!mTearOff || mTearOff->GetInterface() != mInterface) {
     303               0 :             mTearOff = nsnull;
     304               0 :             return NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED;
     305                 :         }
     306                 :     }
     307                 : 
     308                 :     // Refresh in case FindTearOff extended the set
     309         6752344 :     mSet = mWrapper->GetSet();
     310                 : 
     311         6752344 :     mState = READY_TO_CALL;
     312         6752344 :     return NS_OK;
     313                 : }
     314                 : 
     315                 : void
     316               0 : XPCCallContext::SystemIsBeingShutDown()
     317                 : {
     318                 :     // XXX This is pretty questionable since the per thread cleanup stuff
     319                 :     // can be making this call on one thread for call contexts on another
     320                 :     // thread.
     321               0 :     NS_WARNING("Shutting Down XPConnect even through there is a live XPCCallContext");
     322               0 :     mThreadData = nsnull;
     323               0 :     mXPCContext = nsnull;
     324               0 :     mState = SYSTEM_SHUTDOWN;
     325               0 :     if (mPrevCallContext)
     326               0 :         mPrevCallContext->SystemIsBeingShutDown();
     327               0 : }
     328                 : 
     329        15876593 : XPCCallContext::~XPCCallContext()
     330                 : {
     331                 :     // do cleanup...
     332                 : 
     333        15874683 :     bool shouldReleaseXPC = false;
     334                 : 
     335        15874683 :     if (mXPCContext) {
     336        15874683 :         mXPCContext->SetCallingLangType(mPrevCallerLanguage);
     337                 : 
     338                 : #ifdef DEBUG
     339        15874683 :         XPCCallContext* old = mThreadData->SetCallContext(mPrevCallContext);
     340        15874683 :         NS_ASSERTION(old == this, "bad pop from per thread data");
     341                 : #else
     342                 :         (void) mThreadData->SetCallContext(mPrevCallContext);
     343                 : #endif
     344                 : 
     345        15874683 :         shouldReleaseXPC = mPrevCallContext == nsnull;
     346                 :     }
     347                 : 
     348                 :     // NB: Needs to happen before the context stack pop.
     349        15874683 :     if (mJSContext && mCallerLanguage == NATIVE_CALLER)
     350         2642414 :         JS_EndRequest(mJSContext);
     351                 : 
     352        15874683 :     if (mContextPopRequired) {
     353          195436 :         XPCJSContextStack* stack = mThreadData->GetJSContextStack();
     354          195436 :         NS_ASSERTION(stack, "bad!");
     355          195436 :         if (stack) {
     356          390872 :             DebugOnly<JSContext*> poppedCX = stack->Pop();
     357          195436 :             NS_ASSERTION(poppedCX == mJSContext, "bad pop");
     358                 :         }
     359                 :     }
     360                 : 
     361        15874683 :     if (mJSContext) {
     362        15874683 :         if (mDestroyJSContextInDestructor) {
     363                 : #ifdef DEBUG_xpc_hacker
     364                 :             printf("!xpc - doing deferred destruction of JSContext @ %p\n",
     365                 :                    mJSContext);
     366                 : #endif
     367               0 :             NS_ASSERTION(!mThreadData->GetJSContextStack() ||
     368                 :                          !mThreadData->GetJSContextStack()->
     369                 :                          DEBUG_StackHasJSContext(mJSContext),
     370                 :                          "JSContext still in threadjscontextstack!");
     371                 : 
     372               0 :             JS_DestroyContext(mJSContext);
     373                 :         }
     374                 :     }
     375                 : 
     376                 : #ifdef DEBUG
     377        47624049 :     for (PRUint32 i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
     378        31749366 :         NS_ASSERTION(!mScratchStrings[i].mInUse, "Uh, string wrapper still in use!");
     379                 :     }
     380                 : #endif
     381                 : 
     382        15874683 :     if (shouldReleaseXPC && mXPC)
     383         4278171 :         NS_RELEASE(mXPC);
     384        31753186 : }
     385                 : 
     386                 : XPCReadableJSStringWrapper *
     387          258385 : XPCCallContext::NewStringWrapper(const PRUnichar *str, PRUint32 len)
     388                 : {
     389          314904 :     for (PRUint32 i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
     390          298384 :         StringWrapperEntry& ent = mScratchStrings[i];
     391                 : 
     392          298384 :         if (!ent.mInUse) {
     393          241865 :             ent.mInUse = true;
     394                 : 
     395                 :             // Construct the string using placement new.
     396                 : 
     397          241865 :             return new (ent.mString.addr()) XPCReadableJSStringWrapper(str, len);
     398                 :         }
     399                 :     }
     400                 : 
     401                 :     // All our internal string wrappers are used, allocate a new string.
     402                 : 
     403           16520 :     return new XPCReadableJSStringWrapper(str, len);
     404                 : }
     405                 : 
     406                 : void
     407         1599508 : XPCCallContext::DeleteString(nsAString *string)
     408                 : {
     409         4338273 :     for (PRUint32 i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
     410         2980630 :         StringWrapperEntry& ent = mScratchStrings[i];
     411         2980630 :         if (string == ent.mString.addr()) {
     412                 :             // One of our internal strings is no longer in use, mark
     413                 :             // it as such and destroy the string.
     414                 : 
     415          241865 :             ent.mInUse = false;
     416          241865 :             ent.mString.addr()->~XPCReadableJSStringWrapper();
     417                 : 
     418          241865 :             return;
     419                 :         }
     420                 :     }
     421                 : 
     422                 :     // We're done with a string that's not one of our internal
     423                 :     // strings, delete it.
     424         1357643 :     delete string;
     425                 : }
     426                 : 
     427                 : /* readonly attribute nsISupports Callee; */
     428                 : NS_IMETHODIMP
     429               0 : XPCCallContext::GetCallee(nsISupports * *aCallee)
     430                 : {
     431               0 :     nsISupports* temp = mWrapper ? mWrapper->GetIdentityObject() : nsnull;
     432               0 :     NS_IF_ADDREF(temp);
     433               0 :     *aCallee = temp;
     434               0 :     return NS_OK;
     435                 : }
     436                 : 
     437                 : /* readonly attribute PRUint16 CalleeMethodIndex; */
     438                 : NS_IMETHODIMP
     439               0 : XPCCallContext::GetCalleeMethodIndex(PRUint16 *aCalleeMethodIndex)
     440                 : {
     441               0 :     *aCalleeMethodIndex = mMethodIndex;
     442               0 :     return NS_OK;
     443                 : }
     444                 : 
     445                 : /* readonly attribute nsIXPConnectWrappedNative CalleeWrapper; */
     446                 : NS_IMETHODIMP
     447          211137 : XPCCallContext::GetCalleeWrapper(nsIXPConnectWrappedNative * *aCalleeWrapper)
     448                 : {
     449          211137 :     nsIXPConnectWrappedNative* temp = mWrapper;
     450          211137 :     NS_IF_ADDREF(temp);
     451          211137 :     *aCalleeWrapper = temp;
     452          211137 :     return NS_OK;
     453                 : }
     454                 : 
     455                 : /* readonly attribute XPCNativeInterface CalleeInterface; */
     456                 : NS_IMETHODIMP
     457               0 : XPCCallContext::GetCalleeInterface(nsIInterfaceInfo * *aCalleeInterface)
     458                 : {
     459               0 :     nsIInterfaceInfo* temp = mInterface->GetInterfaceInfo();
     460               0 :     NS_IF_ADDREF(temp);
     461               0 :     *aCalleeInterface = temp;
     462               0 :     return NS_OK;
     463                 : }
     464                 : 
     465                 : /* readonly attribute nsIClassInfo CalleeClassInfo; */
     466                 : NS_IMETHODIMP
     467               0 : XPCCallContext::GetCalleeClassInfo(nsIClassInfo * *aCalleeClassInfo)
     468                 : {
     469               0 :     nsIClassInfo* temp = mWrapper ? mWrapper->GetClassInfo() : nsnull;
     470               0 :     NS_IF_ADDREF(temp);
     471               0 :     *aCalleeClassInfo = temp;
     472               0 :     return NS_OK;
     473                 : }
     474                 : 
     475                 : /* readonly attribute JSContextPtr JSContext; */
     476                 : NS_IMETHODIMP
     477              11 : XPCCallContext::GetJSContext(JSContext * *aJSContext)
     478                 : {
     479              11 :     JS_AbortIfWrongThread(JS_GetRuntime(mJSContext));
     480              11 :     *aJSContext = mJSContext;
     481              11 :     return NS_OK;
     482                 : }
     483                 : 
     484                 : /* readonly attribute PRUint32 Argc; */
     485                 : NS_IMETHODIMP
     486               0 : XPCCallContext::GetArgc(PRUint32 *aArgc)
     487                 : {
     488               0 :     *aArgc = (PRUint32) mArgc;
     489               0 :     return NS_OK;
     490                 : }
     491                 : 
     492                 : /* readonly attribute JSValPtr ArgvPtr; */
     493                 : NS_IMETHODIMP
     494               0 : XPCCallContext::GetArgvPtr(jsval * *aArgvPtr)
     495                 : {
     496               0 :     *aArgvPtr = mArgv;
     497               0 :     return NS_OK;
     498                 : }
     499                 : 
     500                 : NS_IMETHODIMP
     501             421 : XPCCallContext::GetPreviousCallContext(nsAXPCNativeCallContext **aResult)
     502                 : {
     503             421 :   NS_ENSURE_ARG_POINTER(aResult);
     504             421 :   *aResult = GetPrevCallContext();
     505             421 :   return NS_OK;
     506                 : }
     507                 : 
     508                 : NS_IMETHODIMP
     509             397 : XPCCallContext::GetLanguage(PRUint16 *aResult)
     510                 : {
     511             397 :   NS_ENSURE_ARG_POINTER(aResult);
     512             397 :   *aResult = GetCallerLanguage();
     513             397 :   return NS_OK;
     514                 : }
     515                 : 
     516                 : #ifdef DEBUG
     517                 : // static
     518                 : void
     519          142781 : XPCLazyCallContext::AssertContextIsTopOfStack(JSContext* cx)
     520                 : {
     521          142781 :     XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
     522          142781 :     XPCJSContextStack* stack = tls->GetJSContextStack();
     523                 : 
     524          142781 :     JSContext *topJSContext = stack->Peek();
     525          142781 :     NS_ASSERTION(cx == topJSContext, "wrong context on XPCJSContextStack!");
     526          142781 : }
     527                 : #endif

Generated by: LCOV version 1.7