LCOV - code coverage report
Current view: top level - dom/xslt/xpath - txXPCOMExtensionFunction.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 251 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsAutoPtr.h"
       7             : #include "nsComponentManagerUtils.h"
       8             : #include "nsDependentString.h"
       9             : #include "nsIAtom.h"
      10             : #include "nsIInterfaceInfoManager.h"
      11             : #include "nsServiceManagerUtils.h"
      12             : #include "txExpr.h"
      13             : #include "txIFunctionEvaluationContext.h"
      14             : #include "txIXPathContext.h"
      15             : #include "txNodeSetAdaptor.h"
      16             : #include "txXPathTreeWalker.h"
      17             : #include "xptcall.h"
      18             : #include "txXPathObjectAdaptor.h"
      19             : #include "mozilla/Attributes.h"
      20             : #include "mozilla/UniquePtr.h"
      21             : #include "mozilla/dom/ScriptSettings.h"
      22             : #include "nsIClassInfo.h"
      23             : #include "nsIInterfaceInfo.h"
      24             : #include "js/RootingAPI.h"
      25             : 
      26           0 : NS_IMPL_ISUPPORTS(txXPathObjectAdaptor, txIXPathObject)
      27             : 
      28             : class txFunctionEvaluationContext final : public txIFunctionEvaluationContext
      29             : {
      30             : public:
      31             :     txFunctionEvaluationContext(txIEvalContext *aContext, nsISupports *aState);
      32             : 
      33             :     NS_DECL_ISUPPORTS
      34             :     NS_DECL_TXIFUNCTIONEVALUATIONCONTEXT
      35             : 
      36           0 :     void ClearContext()
      37             :     {
      38           0 :         mContext = nullptr;
      39           0 :     }
      40             : 
      41             : private:
      42           0 :     ~txFunctionEvaluationContext() {}
      43             : 
      44             :     txIEvalContext *mContext;
      45             :     nsCOMPtr<nsISupports> mState;
      46             : };
      47             : 
      48           0 : txFunctionEvaluationContext::txFunctionEvaluationContext(txIEvalContext *aContext,
      49           0 :                                                          nsISupports *aState)
      50             :     : mContext(aContext),
      51           0 :       mState(aState)
      52             : {
      53           0 : }
      54             : 
      55           0 : NS_IMPL_ISUPPORTS(txFunctionEvaluationContext, txIFunctionEvaluationContext)
      56             : 
      57             : NS_IMETHODIMP
      58           0 : txFunctionEvaluationContext::GetPosition(uint32_t *aPosition)
      59             : {
      60           0 :     NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
      61             : 
      62           0 :     *aPosition = mContext->position();
      63             : 
      64           0 :     return NS_OK;
      65             : }
      66             : 
      67             : NS_IMETHODIMP
      68           0 : txFunctionEvaluationContext::GetSize(uint32_t *aSize)
      69             : {
      70           0 :     NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
      71             : 
      72           0 :     *aSize = mContext->size();
      73             : 
      74           0 :     return NS_OK;
      75             : }
      76             : 
      77             : NS_IMETHODIMP
      78           0 : txFunctionEvaluationContext::GetContextNode(nsIDOMNode **aNode)
      79             : {
      80           0 :     NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
      81             : 
      82           0 :     return txXPathNativeNode::getNode(mContext->getContextNode(), aNode);
      83             : }
      84             : 
      85             : NS_IMETHODIMP
      86           0 : txFunctionEvaluationContext::GetState(nsISupports **aState)
      87             : {
      88           0 :     NS_IF_ADDREF(*aState = mState);
      89             : 
      90           0 :     return NS_OK;
      91             : }
      92             : 
      93             : enum txArgumentType {
      94             :     eBOOLEAN = nsXPTType::T_BOOL,
      95             :     eNUMBER = nsXPTType::T_DOUBLE,
      96             :     eSTRING = nsXPTType::T_DOMSTRING,
      97             :     eNODESET,
      98             :     eCONTEXT,
      99             :     eOBJECT,
     100             :     eUNKNOWN
     101             : };
     102             : 
     103           0 : class txXPCOMExtensionFunctionCall : public FunctionCall
     104             : {
     105             : public:
     106             :     txXPCOMExtensionFunctionCall(nsISupports *aHelper, const nsIID &aIID,
     107             :                                  uint16_t aMethodIndex,
     108             : #ifdef TX_TO_STRING
     109             :                                  nsIAtom *aName,
     110             : #endif
     111             :                                  nsISupports *aState);
     112             : 
     113             :     TX_DECL_FUNCTION
     114             : 
     115             : private:
     116             :     txArgumentType GetParamType(const nsXPTParamInfo &aParam,
     117             :                                 nsIInterfaceInfo *aInfo);
     118             : 
     119             :     nsCOMPtr<nsISupports> mHelper;
     120             :     nsIID mIID;
     121             :     uint16_t mMethodIndex;
     122             : #ifdef TX_TO_STRING
     123             :     nsCOMPtr<nsIAtom> mName;
     124             : #endif
     125             :     nsCOMPtr<nsISupports> mState;
     126             : };
     127             : 
     128           0 : txXPCOMExtensionFunctionCall::txXPCOMExtensionFunctionCall(nsISupports *aHelper,
     129             :                                                            const nsIID &aIID,
     130             :                                                            uint16_t aMethodIndex,
     131             : #ifdef TX_TO_STRING
     132             :                                                            nsIAtom *aName,
     133             : #endif
     134           0 :                                                            nsISupports *aState)
     135             :     : mHelper(aHelper),
     136             :       mIID(aIID),
     137             :       mMethodIndex(aMethodIndex),
     138             : #ifdef TX_TO_STRING
     139             :       mName(aName),
     140             : #endif
     141           0 :       mState(aState)
     142             : {
     143           0 : }
     144             : 
     145             : class txInterfacesArrayHolder
     146             : {
     147             : public:
     148           0 :     txInterfacesArrayHolder(nsIID **aArray, uint32_t aCount) : mArray(aArray),
     149           0 :                                                                mCount(aCount)
     150             :     {
     151           0 :     }
     152           0 :     ~txInterfacesArrayHolder()
     153           0 :     {
     154           0 :         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mArray);
     155           0 :     }
     156             : 
     157             : private:
     158             :     nsIID **mArray;
     159             :     uint32_t mCount;
     160             : };
     161             : 
     162             : static nsresult
     163           0 : LookupFunction(const char *aContractID, nsIAtom* aName, nsIID &aIID,
     164             :                uint16_t &aMethodIndex, nsISupports **aHelper)
     165             : {
     166             :     nsresult rv;
     167           0 :     nsCOMPtr<nsISupports> helper = do_GetService(aContractID, &rv);
     168           0 :     NS_ENSURE_SUCCESS(rv, rv);
     169             : 
     170           0 :     nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(helper, &rv);
     171           0 :     NS_ENSURE_SUCCESS(rv, rv);
     172             : 
     173             :     nsCOMPtr<nsIInterfaceInfoManager> iim =
     174           0 :         do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
     175           0 :     NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
     176             : 
     177           0 :     nsIID** iidArray = nullptr;
     178           0 :     uint32_t iidCount = 0;
     179           0 :     rv = classInfo->GetInterfaces(&iidCount, &iidArray);
     180           0 :     NS_ENSURE_SUCCESS(rv, rv);
     181             : 
     182           0 :     txInterfacesArrayHolder holder(iidArray, iidCount);
     183             : 
     184             :     // Remove any minus signs and uppercase the following letter (so
     185             :     // foo-bar becomes fooBar). Note that if there are any names that already
     186             :     // have uppercase letters they might cause false matches (both fooBar and
     187             :     // foo-bar matching fooBar).
     188           0 :     const char16_t *name = aName->GetUTF16String();
     189           0 :     nsAutoCString methodName;
     190             :     char16_t letter;
     191           0 :     bool upperNext = false;
     192           0 :     while ((letter = *name)) {
     193           0 :         if (letter == '-') {
     194           0 :             upperNext = true;
     195             :         }
     196             :         else {
     197           0 :             MOZ_ASSERT(nsCRT::IsAscii(letter),
     198             :                        "invalid static_cast coming up");
     199           0 :             methodName.Append(upperNext ?
     200           0 :                               nsCRT::ToUpper(static_cast<char>(letter)) :
     201           0 :                               letter);
     202           0 :             upperNext = false;
     203             :         }
     204           0 :         ++name;
     205             :     }
     206             : 
     207             :     uint32_t i;
     208           0 :     for (i = 0; i < iidCount; ++i) {
     209           0 :         nsIID *iid = iidArray[i];
     210             : 
     211           0 :         nsCOMPtr<nsIInterfaceInfo> info;
     212           0 :         rv = iim->GetInfoForIID(iid, getter_AddRefs(info));
     213           0 :         NS_ENSURE_SUCCESS(rv, rv);
     214             : 
     215             :         uint16_t methodIndex;
     216             :         const nsXPTMethodInfo *methodInfo;
     217           0 :         rv = info->GetMethodInfoForName(methodName.get(), &methodIndex,
     218           0 :                                         &methodInfo);
     219           0 :         if (NS_SUCCEEDED(rv)) {
     220             :             // Exclude notxpcom and hidden. Also check that we have at least a
     221             :             // return value (the xpidl compiler ensures that that return value
     222             :             // is the last argument).
     223           0 :             uint8_t paramCount = methodInfo->GetParamCount();
     224           0 :             if (methodInfo->IsNotXPCOM() || methodInfo->IsHidden() ||
     225           0 :                 paramCount == 0 ||
     226           0 :                 !methodInfo->GetParam(paramCount - 1).IsRetval()) {
     227           0 :                 return NS_ERROR_FAILURE;
     228             :             }
     229             : 
     230           0 :             aIID = *iid;
     231           0 :             aMethodIndex = methodIndex;
     232           0 :             return helper->QueryInterface(aIID, (void**)aHelper);
     233             :         }
     234             :     }
     235             : 
     236           0 :     return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
     237             : }
     238             : 
     239             : /* static */
     240             : nsresult
     241           0 : TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID,
     242             :                             nsIAtom* aName, nsISupports *aState,
     243             :                             FunctionCall **aFunction)
     244             : {
     245             :     nsIID iid;
     246           0 :     uint16_t methodIndex = 0;
     247           0 :     nsCOMPtr<nsISupports> helper;
     248             : 
     249           0 :     nsresult rv = LookupFunction(aContractID.get(), aName, iid, methodIndex,
     250           0 :                                  getter_AddRefs(helper));
     251           0 :     NS_ENSURE_SUCCESS(rv, rv);
     252             : 
     253           0 :     if (!aFunction) {
     254           0 :         return NS_OK;
     255             :     }
     256             : 
     257           0 :     *aFunction = new txXPCOMExtensionFunctionCall(helper, iid, methodIndex,
     258             : #ifdef TX_TO_STRING
     259             :                                                   aName,
     260             : #endif
     261           0 :                                                   aState);
     262           0 :     return NS_OK;
     263             : }
     264             : 
     265             : txArgumentType
     266           0 : txXPCOMExtensionFunctionCall::GetParamType(const nsXPTParamInfo &aParam,
     267             :                                            nsIInterfaceInfo *aInfo)
     268             : {
     269           0 :     uint8_t tag = aParam.GetType().TagPart();
     270           0 :     switch (tag) {
     271             :         case nsXPTType::T_BOOL:
     272             :         case nsXPTType::T_DOUBLE:
     273             :         case nsXPTType::T_DOMSTRING:
     274             :         {
     275           0 :             return txArgumentType(tag);
     276             :         }
     277             :         case nsXPTType::T_INTERFACE:
     278             :         case nsXPTType::T_INTERFACE_IS:
     279             :         {
     280             :             nsIID iid;
     281           0 :             aInfo->GetIIDForParamNoAlloc(mMethodIndex, &aParam, &iid);
     282           0 :             if (iid.Equals(NS_GET_IID(txINodeSet))) {
     283           0 :                 return eNODESET;
     284             :             }
     285           0 :             if (iid.Equals(NS_GET_IID(txIFunctionEvaluationContext))) {
     286           0 :                 return eCONTEXT;
     287             :             }
     288           0 :             if (iid.Equals(NS_GET_IID(txIXPathObject))) {
     289           0 :                 return eOBJECT;
     290             :             }
     291           0 :             return eUNKNOWN;
     292             :         }
     293             :         default:
     294             :         {
     295             :             // XXX Error!
     296           0 :             return eUNKNOWN;
     297             :         }
     298             :     }
     299             : }
     300             : 
     301             : class txParamArrayHolder
     302             : {
     303             : public:
     304           0 :     txParamArrayHolder()
     305           0 :         : mCount(0)
     306             :     {
     307           0 :     }
     308           0 :     txParamArrayHolder(txParamArrayHolder&& rhs)
     309           0 :       : mArray(mozilla::Move(rhs.mArray))
     310           0 :       , mCount(rhs.mCount)
     311             :     {
     312           0 :         rhs.mCount = 0;
     313           0 :     }
     314             :     ~txParamArrayHolder();
     315             : 
     316             :     bool Init(uint8_t aCount);
     317           0 :     operator nsXPTCVariant*() const
     318             :     {
     319           0 :       return mArray.get();
     320             :     }
     321             : 
     322           0 :     void trace(JSTracer* trc) {
     323           0 :         for (uint8_t i = 0; i < mCount; ++i) {
     324           0 :             if (mArray[i].type == nsXPTType::T_JSVAL) {
     325           0 :                 JS::UnsafeTraceRoot(trc, &mArray[i].val.j, "txParam value");
     326             :             }
     327             :         }
     328           0 :     }
     329             : 
     330             : private:
     331             :     mozilla::UniquePtr<nsXPTCVariant[]> mArray;
     332             :     uint8_t mCount;
     333             : };
     334             : 
     335           0 : txParamArrayHolder::~txParamArrayHolder()
     336             : {
     337             :     uint8_t i;
     338           0 :     for (i = 0; i < mCount; ++i) {
     339           0 :         nsXPTCVariant &variant = mArray[i];
     340           0 :         if (variant.DoesValNeedCleanup()) {
     341           0 :             if (variant.type.TagPart() == nsXPTType::T_DOMSTRING)
     342           0 :                 delete (nsAString*)variant.val.p;
     343             :             else {
     344           0 :                 MOZ_ASSERT(variant.type.TagPart() == nsXPTType::T_INTERFACE ||
     345             :                            variant.type.TagPart() == nsXPTType::T_INTERFACE_IS,
     346             :                            "We only support cleanup of strings and interfaces "
     347             :                            "here, and this looks like neither!");
     348           0 :                 if (variant.val.p != nullptr) {
     349           0 :                     static_cast<nsISupports*>(variant.val.p)->Release();
     350             :                 }
     351             :             }
     352             :         }
     353             :     }
     354           0 : }
     355             : 
     356             : bool
     357           0 : txParamArrayHolder::Init(uint8_t aCount)
     358             : {
     359           0 :     mCount = aCount;
     360           0 :     mArray = mozilla::MakeUnique<nsXPTCVariant[]>(mCount);
     361           0 :     if (!mArray) {
     362           0 :         return false;
     363             :     }
     364             : 
     365           0 :     memset(mArray.get(), 0, mCount * sizeof(nsXPTCVariant));
     366             : 
     367           0 :     return true;
     368             : }
     369             : 
     370             : nsresult
     371           0 : txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
     372             :                                        txAExprResult** aResult)
     373             : {
     374             :     nsCOMPtr<nsIInterfaceInfoManager> iim =
     375           0 :         do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
     376           0 :     NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
     377             : 
     378           0 :     nsCOMPtr<nsIInterfaceInfo> info;
     379           0 :     nsresult rv = iim->GetInfoForIID(&mIID, getter_AddRefs(info));
     380           0 :     NS_ENSURE_SUCCESS(rv, rv);
     381             : 
     382             :     const nsXPTMethodInfo *methodInfo;
     383           0 :     rv = info->GetMethodInfo(mMethodIndex, &methodInfo);
     384           0 :     NS_ENSURE_SUCCESS(rv, rv);
     385             : 
     386           0 :     uint8_t paramCount = methodInfo->GetParamCount();
     387           0 :     uint8_t inArgs = paramCount - 1;
     388             : 
     389           0 :     JS::Rooted<txParamArrayHolder> invokeParams(mozilla::dom::RootingCx());
     390           0 :     if (!invokeParams.get().Init(paramCount)) {
     391           0 :         return NS_ERROR_OUT_OF_MEMORY;
     392             :     }
     393             : 
     394           0 :     const nsXPTParamInfo &paramInfo = methodInfo->GetParam(0);
     395           0 :     txArgumentType type = GetParamType(paramInfo, info);
     396           0 :     if (type == eUNKNOWN) {
     397           0 :         return NS_ERROR_FAILURE;
     398             :     }
     399             : 
     400             :     txFunctionEvaluationContext *context;
     401           0 :     uint32_t paramStart = 0;
     402           0 :     if (type == eCONTEXT) {
     403           0 :         if (paramInfo.IsOut()) {
     404             :             // We don't support out values.
     405           0 :             return NS_ERROR_FAILURE;
     406             :         }
     407             : 
     408             :         // Create context wrapper.
     409           0 :         context = new txFunctionEvaluationContext(aContext, mState);
     410             : 
     411           0 :         nsXPTCVariant &invokeParam = invokeParams.get()[0];
     412           0 :         invokeParam.type = paramInfo.GetType();
     413           0 :         invokeParam.SetValNeedsCleanup();
     414           0 :         NS_ADDREF((txIFunctionEvaluationContext*&)invokeParam.val.p = context);
     415             : 
     416             :         // Skip first argument, since it's the context.
     417           0 :         paramStart = 1;
     418             :     }
     419             :     else {
     420           0 :         context = nullptr;
     421             :     }
     422             : 
     423             :     // XXX varargs
     424           0 :     if (!requireParams(inArgs - paramStart, inArgs - paramStart, aContext)) {
     425           0 :         return NS_ERROR_FAILURE;
     426             :     }
     427             : 
     428             :     uint32_t i;
     429           0 :     for (i = paramStart; i < inArgs; ++i) {
     430           0 :         Expr* expr = mParams[i - paramStart];
     431             : 
     432           0 :         const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
     433           0 :         txArgumentType type = GetParamType(paramInfo, info);
     434           0 :         if (type == eUNKNOWN) {
     435           0 :             return NS_ERROR_FAILURE;
     436             :         }
     437             : 
     438           0 :         nsXPTCVariant &invokeParam = invokeParams.get()[i];
     439           0 :         if (paramInfo.IsOut()) {
     440             :             // We don't support out values.
     441           0 :             return NS_ERROR_FAILURE;
     442             :         }
     443             : 
     444           0 :         invokeParam.type = paramInfo.GetType();
     445           0 :         switch (type) {
     446             :             case eNODESET:
     447             :             {
     448           0 :                 RefPtr<txNodeSet> nodes;
     449           0 :                 rv = evaluateToNodeSet(expr, aContext, getter_AddRefs(nodes));
     450           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     451             : 
     452           0 :                 txNodeSetAdaptor *adaptor = new txNodeSetAdaptor(nodes);
     453           0 :                 if (!adaptor) {
     454           0 :                     return NS_ERROR_OUT_OF_MEMORY;
     455             :                 }
     456             : 
     457           0 :                 nsCOMPtr<txINodeSet> nodeSet = adaptor;
     458           0 :                 rv = adaptor->Init();
     459           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     460             : 
     461           0 :                 invokeParam.SetValNeedsCleanup();
     462           0 :                 nodeSet.swap((txINodeSet*&)invokeParam.val.p);
     463           0 :                 break;
     464             :             }
     465             :             case eBOOLEAN:
     466             :             {
     467           0 :                 rv = expr->evaluateToBool(aContext, invokeParam.val.b);
     468           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     469             : 
     470           0 :                 break;
     471             :             }
     472             :             case eNUMBER:
     473             :             {
     474             :                 double dbl;
     475           0 :                 rv = evaluateToNumber(mParams[0], aContext, &dbl);
     476           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     477             : 
     478           0 :                 invokeParam.val.d = dbl;
     479           0 :                 break;
     480             :             }
     481             :             case eSTRING:
     482             :             {
     483           0 :                 nsString *value = new nsString();
     484           0 :                 if (!value) {
     485           0 :                     return NS_ERROR_OUT_OF_MEMORY;
     486             :                 }
     487             : 
     488           0 :                 rv = expr->evaluateToString(aContext, *value);
     489           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     490             : 
     491           0 :                 invokeParam.SetValNeedsCleanup();
     492           0 :                 invokeParam.val.p = value;
     493           0 :                 break;
     494             :             }
     495             :             case eOBJECT:
     496             :             {
     497           0 :               RefPtr<txAExprResult> exprRes;
     498           0 :               rv = expr->evaluate(aContext, getter_AddRefs(exprRes));
     499           0 :               NS_ENSURE_SUCCESS(rv, rv);
     500             : 
     501             :               nsCOMPtr<txIXPathObject> adaptor =
     502           0 :                 new txXPathObjectAdaptor(exprRes);
     503           0 :               if (!adaptor) {
     504           0 :                   return NS_ERROR_OUT_OF_MEMORY;
     505             :               }
     506             : 
     507           0 :               invokeParam.SetValNeedsCleanup();
     508           0 :               adaptor.swap((txIXPathObject*&)invokeParam.val.p);
     509           0 :               break;
     510             :             }
     511             :             case eCONTEXT:
     512             :             case eUNKNOWN:
     513             :             {
     514             :                 // We only support passing the context as the *first* argument.
     515           0 :                 return NS_ERROR_FAILURE;
     516             :             }
     517             :         }
     518             :     }
     519             : 
     520           0 :     const nsXPTParamInfo &returnInfo = methodInfo->GetParam(inArgs);
     521           0 :     txArgumentType returnType = GetParamType(returnInfo, info);
     522           0 :     if (returnType == eUNKNOWN) {
     523           0 :         return NS_ERROR_FAILURE;
     524             :     }
     525             : 
     526           0 :     nsXPTCVariant &returnParam = invokeParams.get()[inArgs];
     527           0 :     returnParam.type = returnInfo.GetType();
     528           0 :     if (returnType == eSTRING) {
     529           0 :         nsString *value = new nsString();
     530           0 :         returnParam.SetValNeedsCleanup();
     531           0 :         returnParam.val.p = value;
     532             :     }
     533             :     else {
     534           0 :         returnParam.SetIndirect();
     535           0 :         if (returnType == eNODESET || returnType == eOBJECT) {
     536           0 :             returnParam.SetValNeedsCleanup();
     537             :         }
     538             :     }
     539             : 
     540           0 :     rv = NS_InvokeByIndex(mHelper, mMethodIndex, paramCount, invokeParams.get());
     541             : 
     542             :     // In case someone is holding on to the txFunctionEvaluationContext which
     543             :     // could thus stay alive longer than this function.
     544           0 :     if (context) {
     545           0 :         context->ClearContext();
     546             :     }
     547             : 
     548           0 :     NS_ENSURE_SUCCESS(rv, rv);
     549             : 
     550           0 :     switch (returnType) {
     551             :         case eNODESET:
     552             :         {
     553           0 :             txINodeSet* nodeSet = static_cast<txINodeSet*>(returnParam.val.p);
     554           0 :             nsCOMPtr<txIXPathObject> object = do_QueryInterface(nodeSet, &rv);
     555           0 :             NS_ENSURE_SUCCESS(rv, rv);
     556             : 
     557           0 :             NS_ADDREF(*aResult = object->GetResult());
     558             : 
     559           0 :             return NS_OK;
     560             :         }
     561             :         case eBOOLEAN:
     562             :         {
     563           0 :             aContext->recycler()->getBoolResult(returnParam.val.b, aResult);
     564             : 
     565           0 :             return NS_OK;
     566             :         }
     567             :         case eNUMBER:
     568             :         {
     569           0 :             return aContext->recycler()->getNumberResult(returnParam.val.d,
     570           0 :                                                          aResult);
     571             :         }
     572             :         case eSTRING:
     573             :         {
     574             :             nsString *returned = static_cast<nsString*>
     575           0 :                                             (returnParam.val.p);
     576           0 :             return aContext->recycler()->getStringResult(*returned, aResult);
     577             :         }
     578             :         case eOBJECT:
     579             :         {
     580             :             txIXPathObject *object =
     581           0 :                  static_cast<txIXPathObject*>(returnParam.val.p);
     582             : 
     583           0 :             NS_ADDREF(*aResult = object->GetResult());
     584             : 
     585           0 :             return NS_OK;
     586             :         }
     587             :         default:
     588             :         {
     589             :             // Huh?
     590           0 :             return NS_ERROR_FAILURE;
     591             :         }
     592             :     }
     593             : }
     594             : 
     595             : Expr::ResultType
     596           0 : txXPCOMExtensionFunctionCall::getReturnType()
     597             : {
     598             :     // It doesn't really matter what we return here, but it might
     599             :     // be a good idea to try to keep this as unoptimizable as possible
     600           0 :     return ANY_RESULT;
     601             : }
     602             : 
     603             : bool
     604           0 : txXPCOMExtensionFunctionCall::isSensitiveTo(ContextSensitivity aContext)
     605             : {
     606             :     // It doesn't really matter what we return here, but it might
     607             :     // be a good idea to try to keep this as unoptimizable as possible
     608           0 :     return true;
     609             : }
     610             : 
     611             : #ifdef TX_TO_STRING
     612             : nsresult
     613           0 : txXPCOMExtensionFunctionCall::getNameAtom(nsIAtom** aAtom)
     614             : {
     615           0 :     NS_ADDREF(*aAtom = mName);
     616             : 
     617           0 :     return NS_OK;
     618             : }
     619             : #endif

Generated by: LCOV version 1.13