nsID* iid = (nsID*) params[j].ptr;
nsID* iid = (nsID*) params[j].val.p;
JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,                                   jstring aMethodName, jobjectArray aParams){  nsresult rv;  // Get native XPCOM instance  void* xpcom_obj;  rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);  if (NS_FAILED(rv)) {    ThrowException(env, 0, "Failed to get matching XPCOM object");    return nsnull;  }  JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);  // Get method info  PRUint16 methodIndex;  const nsXPTMethodInfo* methodInfo;  nsIInterfaceInfo* iinfo = inst->InterfaceInfo();  const char* methodName = env->GetStringUTFChars(aMethodName, nsnull);  rv = QueryMethodInfo(iinfo, methodName, &methodIndex, &methodInfo);  env->ReleaseStringUTFChars(aMethodName, methodName);  if (NS_FAILED(rv)) {    ThrowException(env, rv, "GetMethodInfoForName failed");    return nsnull;  }#ifdef DEBUG_JAVAXPCOM  const char* ifaceName;  iinfo->GetNameShared(&ifaceName);  LOG(("===> (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));#endif  // Convert the Java params  PRUint8 paramCount = methodInfo->GetParamCount();  nsXPTCVariant* params = nsnull;  if (paramCount)  {    params = new nsXPTCVariant[paramCount];    if (!params) {      ThrowException(env, NS_ERROR_OUT_OF_MEMORY, "Can't create params array");      return nsnull;    }    for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)    {      LOG(("\t Param %d: ", i));      const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);      if (paramInfo.IsIn() && !paramInfo.IsDipper()) {        rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,                         methodInfo, iinfo, methodIndex, 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();            if (params[i].val.p == nsnull) {              rv = NS_ERROR_OUT_OF_MEMORY;              break;            }            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();            if (params[i].val.p == nsnull) {              rv = NS_ERROR_OUT_OF_MEMORY;              break;            }            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(("out/retval\n"));        params[i].ptr = &(params[i].val);        params[i].type = paramInfo.GetType();        params[i].flags = nsXPTCVariant::PTR_IS_DATA;      }    }    if (NS_FAILED(rv)) {      ThrowException(env, rv, "SetupParams failed");      return nsnull;    }  }  // Call the XPCOM method  nsresult invokeResult;  invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), methodIndex,                                    paramCount, params);  // Clean up params  jobject result = nsnull;  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, methodIndex,                          params, params[i]);    } else {      rv = SetRetval(env, paramInfo, methodInfo, iinfo, methodIndex, params,                     params[i], &result);    }  }  if (NS_FAILED(rv)) {    ThrowException(env, rv, "FinalizeParams/SetRetval failed");    return nsnull;  }  // 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");    ThrowException(env, invokeResult, message.get());  }  LOG(("<=== (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));  return result;}