ThrowXPCOMException(env, 0, "Failed to get matching XPCOM object");
ThrowException(env, 0, "Failed to get matching XPCOM object");
CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,                jint aMethodIndex, jobjectArray aParams, jvalue &aResult){  // Find corresponding XPCOM object  void* xpcomObj = GetMatchingXPCOMObject(env, aJavaObject);  if (xpcomObj == nsnull) {    ThrowXPCOMException(env, 0, "Failed to get matching XPCOM object");    return;  }  NS_ASSERTION(!IsXPTCStub(xpcomObj),               "Expected JavaXPCOMInstance, but got nsJavaXPTCStub");  JavaXPCOMInstance* inst = (JavaXPCOMInstance*) xpcomObj;  // Get method info  const nsXPTMethodInfo* methodInfo;  nsIInterfaceInfo* iinfo = inst->InterfaceInfo();  nsresult rv = iinfo->GetMethodInfo(aMethodIndex, &methodInfo);  if (NS_FAILED(rv)) {    ThrowXPCOMException(env, rv, "GetMethodInfo failed");    return;  }#ifdef DEBUG  const char* ifaceName;  iinfo->GetNameShared(&ifaceName);  LOG(("=> Calling %s::%s()\n", ifaceName, methodInfo->GetName()));#endif  // Convert the Java params  PRUint8 paramCount = methodInfo->GetParamCount();  nsXPTCVariant* params = nsnull;  if (paramCount)  {    params = new nsXPTCVariant[paramCount];    for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)    {      LOG(("\t Param %d: ", i));      const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);      if (!paramInfo.IsRetval() && !paramInfo.IsDipper()) {        rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,                         methodInfo, iinfo, aMethodIndex, params, params[i]);      } else if (paramInfo.IsDipper()) {        LOG(("dipper"));        const nsXPTType &type = paramInfo.GetType();        switch (type.TagPart())        {          case nsXPTType::T_ASTRING:          case nsXPTType::T_DOMSTRING:            params[i].val.p = params[i].ptr = new nsString();            params[i].type = type;            params[i].flags = nsXPTCVariant::PTR_IS_DATA |                              nsXPTCVariant::VAL_IS_DOMSTR;            break;          case nsXPTType::T_UTF8STRING:          case nsXPTType::T_CSTRING:            params[i].val.p = params[i].ptr = new nsCString();            params[i].type = type;            params[i].flags = nsXPTCVariant::PTR_IS_DATA |                              nsXPTCVariant::VAL_IS_CSTR;            break;          default:            LOG(("unhandled dipper type\n"));            rv = NS_ERROR_UNEXPECTED;        }      } else {        LOG(("retval\n"));        params[i].ptr = &(params[i].val);        params[i].type = paramInfo.GetType();        params[i].flags = nsXPTCVariant::PTR_IS_DATA;      }    }    if (NS_FAILED(rv)) {      ThrowXPCOMException(env, rv, "SetupParams failed");      return;    }  }  // Call the XPCOM method  nsresult invokeResult;  invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), aMethodIndex,                                    paramCount, params);  // Clean up params  for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)  {    const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);    if (!paramInfo.IsRetval()) {      rv = FinalizeParams(env, env->GetObjectArrayElement(aParams, i),                          paramInfo, methodInfo, iinfo, aMethodIndex,                          params, params[i]);    } else {      rv = SetRetval(env, paramInfo, methodInfo, iinfo, aMethodIndex, params,                     params[i], aResult);    }  }  if (NS_FAILED(rv)) {    ThrowXPCOMException(env, rv, "FinalizeParams failed");    return;  }  // Normally, we would delete any created nsID object in the above loop.  // However, GetIIDForMethodParam may need some of the nsID params when it's  // looking for the IID of an INTERFACE_IS.  Therefore, we can't delete it  // until we've gone through the 'Finalize' loop once and created the result.  for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++)  {    const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);    const nsXPTType &type = paramInfo.GetType();    if (type.TagPart() == nsXPTType::T_IID) {      nsID* iid = (nsID*) params[j].ptr;      delete iid;    }  }  if (params) {    delete params;  }  // If the XPCOM method invocation failed, we don't immediately throw an  // exception and return so that we can clean up any parameters.  if (NS_FAILED(invokeResult)) {    nsCAutoString message("The function \"");    message.AppendASCII(methodInfo->GetName());    message.AppendLiteral("\" returned an error condition");    ThrowXPCOMException(env, invokeResult, message.get());  }  return;}