} else if (isXPTCStub) { aVariant.SetValIsAllocated();  } else { xpcom_obj->Release();
SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,            const nsXPTMethodInfo* aMethodInfo, nsIInterfaceInfo* aIInfo,            PRUint16 aMethodIndex, nsXPTCVariant* aDispatchParams,            nsXPTCVariant &aVariant){  nsresult rv = NS_OK;  const nsXPTType &type = aParamInfo.GetType();  // defaults  aVariant.ptr = nsnull;  aVariant.type = type;  aVariant.flags = 0;  PRUint8 tag = type.TagPart();  switch (tag)  {    case nsXPTType::T_I8:    case nsXPTType::T_U8:    {      LOG(("byte\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.u8 = env->CallByteMethod(aParam, byteValueMID);      } else {  // 'inout'        if (aParam) {          env->GetByteArrayRegion((jbyteArray) aParam, 0, 1,                                  (jbyte*) &(aVariant.val.u8));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_I16:    case nsXPTType::T_U16:    {      LOG(("short\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.u16 = env->CallShortMethod(aParam, shortValueMID);      } else {  // 'inout'        if (aParam) {          env->GetShortArrayRegion((jshortArray) aParam, 0, 1,                                   (jshort*) &(aVariant.val.u16));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_I32:    case nsXPTType::T_U32:    {      LOG(("int\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.u32 = env->CallIntMethod(aParam, intValueMID);      } else {  // 'inout'        if (aParam) {          env->GetIntArrayRegion((jintArray) aParam, 0, 1,                                 (jint*) &(aVariant.val.u32));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_I64:    case nsXPTType::T_U64:    {      LOG(("long\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.u64 = env->CallLongMethod(aParam, longValueMID);      } else {  // 'inout'        if (aParam) {          env->GetLongArrayRegion((jlongArray) aParam, 0, 1,                                  (jlong*) &(aVariant.val.u64));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_FLOAT:    {      LOG(("float\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.f = env->CallFloatMethod(aParam, floatValueMID);      } else {  // 'inout'        if (aParam) {          env->GetFloatArrayRegion((jfloatArray) aParam, 0, 1,                                   (jfloat*) &(aVariant.val.f));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_DOUBLE:    {      LOG(("double\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.d = env->CallDoubleMethod(aParam, doubleValueMID);      } else {  // 'inout'        if (aParam) {          env->GetDoubleArrayRegion((jdoubleArray) aParam, 0, 1,                                    (jdouble*) &(aVariant.val.d));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_BOOL:    {      LOG(("boolean\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.b = env->CallBooleanMethod(aParam, booleanValueMID);      } else {  // 'inout'        if (aParam) {          env->GetBooleanArrayRegion((jbooleanArray) aParam, 0, 1,                                     (jboolean*) &(aVariant.val.b));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_CHAR:    case nsXPTType::T_WCHAR:    {      LOG(("char\n"));      if (!aParamInfo.IsOut()) {  // 'in'        if (tag == nsXPTType::T_CHAR)          aVariant.val.c = env->CallCharMethod(aParam, charValueMID);        else          aVariant.val.wc = env->CallCharMethod(aParam, charValueMID);      } else {  // 'inout'        if (aParam) {          if (tag == nsXPTType::T_CHAR)            env->GetCharArrayRegion((jcharArray) aParam, 0, 1,                                    (jchar*) &(aVariant.val.c));          else            env->GetCharArrayRegion((jcharArray) aParam, 0, 1,                                    (jchar*) &(aVariant.val.wc));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_CHAR_STR:    case nsXPTType::T_WCHAR_STR:    {      LOG(("String\n"));      jstring data = nsnull;      if (!aParamInfo.IsOut()) {  // 'in'        data = (jstring) aParam;      } else {  // 'inout'        if (aParam)          data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam, 0);      }      void* buf = nsnull;      if (data) {        jsize uniLength = env->GetStringLength(data);        if (uniLength > 0) {          if (tag == nsXPTType::T_CHAR_STR) {            jsize utf8Length = env->GetStringUTFLength(data);            buf = nsMemory::Alloc(utf8Length + 1);            if (!buf) {              rv = NS_ERROR_OUT_OF_MEMORY;              break;            }            env->GetStringUTFRegion(data, 0, uniLength, (char*) buf);            ((char*)buf)[utf8Length] = '\0';          } else {  // if T_WCHAR_STR            buf = nsMemory::Alloc((uniLength + 1) * sizeof(jchar));            if (!buf) {              rv = NS_ERROR_OUT_OF_MEMORY;              break;            }            env->GetStringRegion(data, 0, uniLength, (jchar*) buf);            ((jchar*)buf)[uniLength] = '\0';          }        } else {          // create empty string          buf = nsMemory::Alloc(2);          if (!buf) {            rv = NS_ERROR_OUT_OF_MEMORY;            break;          }          ((jchar*)buf)[0] = '\0';        }      }      aVariant.val.p = buf;      if (aParamInfo.IsOut()) { // 'inout'        aVariant.ptr = &aVariant.val;        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_IID:    {      LOG(("String(IID)\n"));      jstring data = nsnull;      if (!aParamInfo.IsOut()) {  // 'in'        data = (jstring) aParam;      } else {  // 'inout'        if (aParam)          data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam, 0);      }      nsID* iid = new nsID;      if (!iid) {        rv = NS_ERROR_OUT_OF_MEMORY;        break;      }      if (data) {        // extract IID string from Java string        const char* str = env->GetStringUTFChars(data, nsnull);        if (!str) {          rv = NS_ERROR_OUT_OF_MEMORY;          break;        }        // parse string into IID object        iid->Parse(str);        env->ReleaseStringUTFChars(data, str);      } else {        *iid = nullID;      }      aVariant.val.p = iid;      if (aParamInfo.IsOut()) { // 'inout'        aVariant.ptr = &aVariant.val;        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_INTERFACE:    case nsXPTType::T_INTERFACE_IS:    {      LOG(("nsISupports\n"));      jobject java_obj = nsnull;      if (!aParamInfo.IsOut()) {  // 'in'        java_obj = (jobject) aParam;      } else {  // 'inout'        if (aParam)          java_obj = (jobject)                       env->GetObjectArrayElement((jobjectArray) aParam, 0);      }      nsISupports* xpcom_obj;      if (java_obj) {        // Get IID for this param        nsID iid;        rv = GetIIDForMethodParam(aIInfo, aMethodInfo, aParamInfo,                                  aMethodIndex, aDispatchParams, PR_TRUE,                                  iid);        if (NS_FAILED(rv))          break;        // If the requested interface is nsIWeakReference, then we look for or        // create a stub for the nsISupports interface.  Then we create a weak        // reference from that stub.        PRBool isWeakRef;        if (iid.Equals(NS_GET_IID(nsIWeakReference))) {          isWeakRef = PR_TRUE;          iid = NS_GET_IID(nsISupports);        } else {          isWeakRef = PR_FALSE;        }        PRBool isXPTCStub;        rv = GetNewOrUsedXPCOMObject(env, java_obj, iid, &xpcom_obj,                                     &isXPTCStub);        if (NS_FAILED(rv))          break;        // If the function expects a weak reference, then we need to        // create it here.        if (isWeakRef) {          if (isXPTCStub) {            nsJavaXPTCStub* stub = NS_STATIC_CAST(nsJavaXPTCStub*,                                                 NS_STATIC_CAST(nsXPTCStubBase*,                                                                xpcom_obj));            nsJavaXPTCStubWeakRef* weakref;            weakref = new nsJavaXPTCStubWeakRef(env, java_obj, stub);            if (!weakref) {              rv = NS_ERROR_OUT_OF_MEMORY;              break;            }            xpcom_obj = weakref;            NS_ADDREF(xpcom_obj);            aVariant.SetValIsAllocated();          } else { // if is native XPCOM object            nsCOMPtr<nsISupportsWeakReference> supportsweak =                                                   do_QueryInterface(xpcom_obj);            if (supportsweak) {              nsWeakPtr weakref;              supportsweak->GetWeakReference(getter_AddRefs(weakref));              xpcom_obj = weakref;              NS_ADDREF(xpcom_obj);            } else {              xpcom_obj = nsnull;            }          }        } else if (isXPTCStub) {          aVariant.SetValIsAllocated();        } else { // if is native XPCOM object          xpcom_obj->Release();        }      } else {        xpcom_obj = nsnull;      }      aVariant.val.p = xpcom_obj;      aVariant.SetValIsInterface();      if (aParamInfo.IsOut()) { // 'inout'        aVariant.ptr = &aVariant.val;        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_ASTRING:    case nsXPTType::T_DOMSTRING:    {      LOG(("String\n"));      jstring data = nsnull;      if (!aParamInfo.IsOut()) {  // 'in'        data = (jstring) aParam;      } else {  // 'inout'        if (aParam)          data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam, 0);      }      nsAString* str;      if (data) {        str = jstring_to_nsAString(env, data);        if (!str) {          rv = NS_ERROR_OUT_OF_MEMORY;          break;        }      } else {        str = nsnull;      }      aVariant.val.p = str;      aVariant.SetValIsDOMString();      if (aParamInfo.IsOut()) { // 'inout'        aVariant.ptr = &aVariant.val;        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_UTF8STRING:    case nsXPTType::T_CSTRING:    {      LOG(("StringUTF\n"));      jstring data = nsnull;      if (!aParamInfo.IsOut()) {  // 'in'        data = (jstring) aParam;      } else {  // 'inout'        if (aParam)          data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam, 0);      }      nsACString* str;      if (data) {        str = jstring_to_nsACString(env, data);        if (!str) {          rv = NS_ERROR_OUT_OF_MEMORY;          break;        }      } else {        str = nsnull;      }      aVariant.val.p = str;      if (tag == nsXPTType::T_CSTRING) {        aVariant.SetValIsCString();      } else {        aVariant.SetValIsUTF8String();      }      if (aParamInfo.IsOut()) { // 'inout'        aVariant.ptr = &aVariant.val;        aVariant.SetPtrIsData();      }    }    break;    // handle "void *" as an "int" in Java    case nsXPTType::T_VOID:    {      LOG(("int (void*)\n"));      if (!aParamInfo.IsOut()) {  // 'in'        aVariant.val.p = (void*) env->CallIntMethod(aParam, intValueMID);      } else {  // 'inout'        if (aParam) {          env->GetIntArrayRegion((jintArray) aParam, 0, 1,                                 (jint*) &(aVariant.val.p));          aVariant.ptr = &aVariant.val;        } else {          aVariant.ptr = nsnull;        }        aVariant.SetPtrIsData();      }    }    break;    case nsXPTType::T_ARRAY:      NS_WARNING("array types are not yet supported");      return NS_ERROR_NOT_IMPLEMENTED;    case nsXPTType::T_PSTRING_SIZE_IS:    case nsXPTType::T_PWSTRING_SIZE_IS:    default:      NS_WARNING("unexpected parameter type");      return NS_ERROR_UNEXPECTED;  }  return rv;}