diff --git a/src/main/c/jni/org_jpy_PyLib.c b/src/main/c/jni/org_jpy_PyLib.c index afc4e751..8f4e9e70 100644 --- a/src/main/c/jni/org_jpy_PyLib.c +++ b/src/main/c/jni/org_jpy_PyLib.c @@ -1858,13 +1858,11 @@ JNIEXPORT jobjectArray JNICALL Java_org_jpy_PyLib_getObjectArrayValue for (i = 0; i < length; i++) { pyItem = PySequence_GetItem(pyObject, i); if (pyItem == NULL) { - (*jenv)->DeleteLocalRef(jenv, jObject); - jObject = NULL; + JPy_DELETE_LOCAL_REF(jObject); goto error; } if (JPy_AsJObject(jenv, pyItem, &jItem, JNI_FALSE) < 0) { - (*jenv)->DeleteLocalRef(jenv, jObject); - jObject = NULL; + JPy_DELETE_LOCAL_REF(jObject); JPy_DIAG_PRINT(JPy_DIAG_F_ALL, "Java_org_jpy_PyLib_getObjectArrayValue: error: failed to convert Python item to Java Object\n"); PyLib_HandlePythonException(jenv); goto error; @@ -1872,8 +1870,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_jpy_PyLib_getObjectArrayValue JPy_XDECREF(pyItem); (*jenv)->SetObjectArrayElement(jenv, jObject, i, jItem); if ((*jenv)->ExceptionCheck(jenv)) { - (*jenv)->DeleteLocalRef(jenv, jObject); - jObject = NULL; + JPy_DELETE_LOCAL_REF(jObject); goto error; } } @@ -2337,9 +2334,9 @@ PyObject* PyLib_CallAndReturnObject(JNIEnv *jenv, PyObject* pyObject, jboolean i } pyArg = PyLib_FromJObjectForTuple(jenv, jArg, jParamClass, nameChars, i); if (jParamClass != NULL) { - (*jenv)->DeleteLocalRef(jenv, jParamClass); - jParamClass = NULL; + JPy_DELETE_LOCAL_REF(jParamClass); } + JPy_DELETE_LOCAL_REF(jArg); if (pyArg == NULL) { JPy_DIAG_PRINT(JPy_DIAG_F_ALL, "PyLib_CallAndReturnObject: error: callable '%s': argument %d: failed to convert Java into Python object\n", nameChars, i); PyLib_HandlePythonException(jenv); diff --git a/src/main/c/jpy_conv.c b/src/main/c/jpy_conv.c index ee7c1a66..1af0c8d4 100644 --- a/src/main/c/jpy_conv.c +++ b/src/main/c/jpy_conv.c @@ -163,7 +163,7 @@ char* JPy_GetTypeName(JNIEnv* jenv, jclass classRef) typeNameCopy = JPy_CopyUTFString(jTypeNameChars); (*jenv)->ReleaseStringUTFChars(jenv, jTypeName, jTypeNameChars); } - (*jenv)->DeleteLocalRef(jenv, jTypeName); + JPy_DELETE_LOCAL_REF(jTypeName); return typeNameCopy; } @@ -190,7 +190,7 @@ PyObject* JPy_FromTypeName(JNIEnv* jenv, jclass classRef) pyTypeName = Py_BuildValue("s", jTypeNameChars); (*jenv)->ReleaseStringUTFChars(jenv, jTypeName, jTypeNameChars); } - (*jenv)->DeleteLocalRef(jenv, jTypeName); + JPy_DELETE_LOCAL_REF(jTypeName); return pyTypeName; } diff --git a/src/main/c/jpy_jmethod.c b/src/main/c/jpy_jmethod.c index 9a48de77..f315758a 100644 --- a/src/main/c/jpy_jmethod.c +++ b/src/main/c/jpy_jmethod.c @@ -307,12 +307,12 @@ PyObject* JMethod_InvokeMethod(JNIEnv* jenv, JPy_JMethod* method, PyObject* pyAr jstring v = (*jenv)->CallStaticObjectMethodA(jenv, classRef, method->mid, jArgs); JPy_ON_JAVA_EXCEPTION_GOTO(error); returnValue = JPy_FromJString(jenv, v); - (*jenv)->DeleteLocalRef(jenv, v); + JPy_DELETE_LOCAL_REF(v); } else { jobject v = (*jenv)->CallStaticObjectMethodA(jenv, classRef, method->mid, jArgs); JPy_ON_JAVA_EXCEPTION_GOTO(error); returnValue = JMethod_FromJObject(jenv, method, pyArgs, jArgs, 0, returnType, v); - (*jenv)->DeleteLocalRef(jenv, v); + JPy_DELETE_LOCAL_REF(v); } } else { @@ -365,12 +365,12 @@ PyObject* JMethod_InvokeMethod(JNIEnv* jenv, JPy_JMethod* method, PyObject* pyAr jstring v = (*jenv)->CallObjectMethodA(jenv, objectRef, method->mid, jArgs); JPy_ON_JAVA_EXCEPTION_GOTO(error); returnValue = JPy_FromJString(jenv, v); - (*jenv)->DeleteLocalRef(jenv, v); + JPy_DELETE_LOCAL_REF(v); } else { jobject v = (*jenv)->CallObjectMethodA(jenv, objectRef, method->mid, jArgs); JPy_ON_JAVA_EXCEPTION_GOTO(error); returnValue = JMethod_FromJObject(jenv, method, pyArgs, jArgs, 1, returnType, v); - (*jenv)->DeleteLocalRef(jenv, v); + JPy_DELETE_LOCAL_REF(v); } } diff --git a/src/main/c/jpy_jobj.c b/src/main/c/jpy_jobj.c index 6762b2c6..baf07062 100644 --- a/src/main/c/jpy_jobj.c +++ b/src/main/c/jpy_jobj.c @@ -88,7 +88,8 @@ int JObj_init_internal(JNIEnv* jenv, JPy_JObj* self, PyObject* args, PyObject* k JPy_JType* jType; PyObject* constructor; JPy_JMethod* jMethod; - jobject objectRef; + jobject localObjectRef; + jobject globalObjectRef; jvalue* jArgs; JPy_ArgDisposer* jDisposers; int isVarArgsArray; @@ -123,10 +124,10 @@ int JObj_init_internal(JNIEnv* jenv, JPy_JObj* self, PyObject* args, PyObject* k JPy_DIAG_PRINT(JPy_DIAG_F_MEM, "JObj_init: calling Java constructor %s\n", jType->javaName); - objectRef = (*jenv)->NewObjectA(jenv, jType->classRef, jMethod->mid, jArgs); + localObjectRef = (*jenv)->NewObjectA(jenv, jType->classRef, jMethod->mid, jArgs); JPy_ON_JAVA_EXCEPTION_RETURN(-1); - if (objectRef == NULL) { + if (localObjectRef == NULL) { PyErr_NoMemory(); return -1; } @@ -135,18 +136,19 @@ int JObj_init_internal(JNIEnv* jenv, JPy_JObj* self, PyObject* args, PyObject* k JMethod_DisposeJArgs(jenv, jMethod->paramCount, jArgs, jDisposers); } - objectRef = (*jenv)->NewGlobalRef(jenv, objectRef); - if (objectRef == NULL) { + globalObjectRef = (*jenv)->NewGlobalRef(jenv, localObjectRef); + if (globalObjectRef == NULL) { PyErr_NoMemory(); return -1; } + JPy_DELETE_LOCAL_REF(localObjectRef); // Note: __init__ may be called multiple times, so we have to release the old objectRef if (self->objectRef != NULL) { (*jenv)->DeleteGlobalRef(jenv, self->objectRef); } - self->objectRef = objectRef; + self->objectRef = globalObjectRef; JPy_DIAG_PRINT(JPy_DIAG_F_MEM, "JObj_init: self->objectRef=%p\n", self->objectRef); @@ -349,7 +351,7 @@ PyObject* JObj_str(JPy_JObj* self) returnValue = JPy_FromJString(jenv, stringRef); error: - (*jenv)->DeleteLocalRef(jenv, stringRef); + JPy_DELETE_LOCAL_REF(stringRef); return returnValue; } @@ -509,7 +511,7 @@ PyObject* JObj_getattro(JPy_JObj* self, PyObject* name) jobject item = (*jenv)->GetObjectField(jenv, self->objectRef, field->fid); JPy_ON_JAVA_EXCEPTION_RETURN(NULL); returnValue = JPy_FromJObjectWithType(jenv, item, field->type); - (*jenv)->DeleteLocalRef(jenv, item); + JPy_DELETE_LOCAL_REF(item); return returnValue; } } else { @@ -608,7 +610,7 @@ PyObject* JObj_sq_item(JPy_JObj* self, Py_ssize_t index) jobject item = (*jenv)->GetObjectArrayElement(jenv, self->objectRef, (jsize) index); JPy_ON_JAVA_EXCEPTION_RETURN(NULL); returnValue = JPy_FromJObjectWithType(jenv, item, type->componentType); - (*jenv)->DeleteLocalRef(jenv, item); + JPy_DELETE_LOCAL_REF(item); return returnValue; } } diff --git a/src/main/c/jpy_jtype.c b/src/main/c/jpy_jtype.c index 90e4841d..8848565c 100644 --- a/src/main/c/jpy_jtype.c +++ b/src/main/c/jpy_jtype.c @@ -57,7 +57,7 @@ JPy_JType* JType_GetTypeForObject(JNIEnv* jenv, jobject objectRef, jboolean reso jclass classRef; classRef = (*jenv)->GetObjectClass(jenv, objectRef); type = JType_GetType(jenv, classRef, resolve); - (*jenv)->DeleteLocalRef(jenv, classRef); + JPy_DELETE_LOCAL_REF(classRef); return type; } @@ -66,6 +66,7 @@ JPy_JType* JType_GetTypeForName(JNIEnv* jenv, const char* typeName, jboolean res { const char* resourceName; jclass classRef; + JPy_JType *result; JPy_JType* javaType = NULL; if (strcmp(typeName, "boolean") == 0) { @@ -124,7 +125,9 @@ JPy_JType* JType_GetTypeForName(JNIEnv* jenv, const char* typeName, jboolean res return NULL; } - return JType_GetType(jenv, classRef, resolve); + result = JType_GetType(jenv, classRef, resolve); + JPy_DELETE_LOCAL_REF(classRef); + return result; } /** @@ -269,7 +272,21 @@ JPy_JType* JType_New(JNIEnv* jenv, jclass classRef, jboolean resolve) } type->isPrimitive = (*jenv)->CallBooleanMethod(jenv, type->classRef, JPy_Class_IsPrimitive_MID); + if ((*jenv)->ExceptionCheck(jenv)) { + (*jenv)->ExceptionClear(jenv); + PyMem_Del(type->javaName); + type->javaName = NULL; + metaType->tp_free(type); + return NULL; + } type->isInterface = (*jenv)->CallBooleanMethod(jenv, type->classRef, JPy_Class_IsInterface_MID); + if ((*jenv)->ExceptionCheck(jenv)) { + (*jenv)->ExceptionClear(jenv); + PyMem_Del(type->javaName); + type->javaName = NULL; + metaType->tp_free(type); + return NULL; + } JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_New: javaName=\"%s\", resolve=%d, type=%p\n", type->javaName, resolve, type); @@ -328,7 +345,7 @@ PyObject* JType_ConvertJavaToPythonObject(JNIEnv* jenv, JPy_JType* type, jobject if (jPyObject != NULL) { // We know that jPyObject is of the proper type, no need to check it. jlong value = (*jenv)->CallLongMethod(jenv, jPyObject, JPy_PyObject_GetPointer_MID); - (*jenv)->DeleteLocalRef(jenv, jPyObject); + JPy_DELETE_LOCAL_REF(jPyObject); JPy_ON_JAVA_EXCEPTION_RETURN(NULL); PyObject* pyObj = (PyObject*) value; JPy_INCREF(pyObj); @@ -544,7 +561,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jboolean* items = (*jenv)->GetBooleanArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -552,14 +569,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseBooleanArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JBOOLEAN(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseBooleanArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -574,7 +591,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jbyte* items = (*jenv)->GetByteArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -582,14 +599,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseByteArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JBYTE(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseByteArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -604,7 +621,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jchar* items = (*jenv)->GetCharArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -612,14 +629,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseCharArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JCHAR(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseCharArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -634,7 +651,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jshort* items = (*jenv)->GetShortArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -642,14 +659,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseShortArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JSHORT(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseShortArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -664,7 +681,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jint* items = (*jenv)->GetIntArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -672,14 +689,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseIntArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JINT(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseIntArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -694,7 +711,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jlong* items = (*jenv)->GetLongArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -702,14 +719,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseLongArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JLONG(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseLongArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -724,7 +741,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jfloat* items = (*jenv)->GetFloatArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -732,14 +749,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseFloatArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JFLOAT(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseFloatArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -754,7 +771,7 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr if (itemCount > 0) { jdouble* items = (*jenv)->GetDoubleArrayElements(jenv, arrayRef, NULL); if (items == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); PyErr_NoMemory(); return -1; } @@ -762,14 +779,14 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { (*jenv)->ReleaseDoubleArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } items[index] = JPy_AS_JDOUBLE(pyItem); JPy_DECREF(pyItem); if (PyErr_Occurred()) { (*jenv)->ReleaseDoubleArrayElements(jenv, arrayRef, items, 0); - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } } @@ -785,19 +802,19 @@ int JType_CreateJavaArray(JNIEnv* jenv, JPy_JType* componentType, PyObject* pyAr for (index = 0; index < itemCount; index++) { pyItem = PySequence_GetItem(pyArg, index); if (pyItem == NULL) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); return -1; } if (JType_ConvertPythonToJavaObject(jenv, componentType, pyItem, &jItem, allowObjectWrapping) < 0) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); + JPy_DELETE_LOCAL_REF(arrayRef); JPy_DECREF(pyItem); return -1; } JPy_DECREF(pyItem); (*jenv)->SetObjectArrayElement(jenv, arrayRef, index, jItem); if ((*jenv)->ExceptionCheck(jenv)) { - (*jenv)->DeleteLocalRef(jenv, arrayRef); - (*jenv)->DeleteLocalRef(jenv, jItem); + JPy_DELETE_LOCAL_REF(arrayRef); + JPy_DELETE_LOCAL_REF(jItem); JPy_HandleJavaException(jenv); return -1; } @@ -831,7 +848,7 @@ int JType_ConvertPythonToJavaObject(JNIEnv* jenv, JPy_JType* type, PyObject* pyA jclass jobjclass = (*jenv)->GetObjectClass(jenv, jobj); if ((*jenv)->IsAssignableFrom(jenv, jobjclass, type->classRef)) { - (*jenv)->DeleteLocalRef(jenv, jobjclass); + JPy_DELETE_LOCAL_REF(jobjclass); JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_ConvertPythonToJavaObject: unwrapping JObj into type->javaName=\"%s\"\n", type->javaName); @@ -843,7 +860,7 @@ int JType_ConvertPythonToJavaObject(JNIEnv* jenv, JPy_JType* type, PyObject* pyA } return 0; } - (*jenv)->DeleteLocalRef(jenv, jobjclass); + JPy_DELETE_LOCAL_REF(jobjclass); } // If it is already a Java type wrapper JType, and assignable, then we are done @@ -852,7 +869,7 @@ int JType_ConvertPythonToJavaObject(JNIEnv* jenv, JPy_JType* type, PyObject* pyA jclass jobjclass = (*jenv)->GetObjectClass(jenv, jobj); if ((*jenv)->IsAssignableFrom(jenv, jobjclass, type->classRef)) { - (*jenv)->DeleteLocalRef(jenv, jobjclass); + JPy_DELETE_LOCAL_REF(jobjclass); JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_ConvertPythonToJavaObject: unwrapping JType into type->javaName=\"%s\"\n", type->javaName); @@ -864,7 +881,7 @@ int JType_ConvertPythonToJavaObject(JNIEnv* jenv, JPy_JType* type, PyObject* pyA } return 0; } - (*jenv)->DeleteLocalRef(jenv, jobjclass); + JPy_DELETE_LOCAL_REF(jobjclass); } if (type->componentType != NULL) { @@ -1041,8 +1058,10 @@ int JType_InitComponentType(JNIEnv* jenv, JPy_JType* type, jboolean resolve) jclass componentTypeRef; componentTypeRef = (jclass) (*jenv)->CallObjectMethod(jenv, type->classRef, JPy_Class_GetComponentType_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); if (componentTypeRef != NULL) { type->componentType = JType_GetType(jenv, componentTypeRef, resolve); + JPy_DELETE_LOCAL_REF(componentTypeRef); if (type->componentType == NULL) { return -1; } @@ -1065,7 +1084,7 @@ int JType_InitSuperType(JNIEnv* jenv, JPy_JType* type, jboolean resolve) return -1; } JPy_INCREF(type->superType); - (*jenv)->DeleteLocalRef(jenv, superClassRef); + JPy_DELETE_LOCAL_REF(superClassRef); } else if (type->isInterface && JPy_JObject != NULL) { // This solves the problems that java.lang.Object methods can not be called on interfaces (https://github.com/bcdev/jpy/issues/57) type->superType = JPy_JObject; @@ -1095,6 +1114,7 @@ int JType_ProcessClassConstructors(JNIEnv* jenv, JPy_JType* type) classRef = type->classRef; methodKey = Py_BuildValue("s", JPy_JTYPE_ATTR_NAME_JINIT); constructors = (*jenv)->CallObjectMethod(jenv, classRef, JPy_Class_GetDeclaredConstructors_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); constrCount = (*jenv)->GetArrayLength(jenv, constructors); JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_ProcessClassConstructors: constrCount=%d\n", constrCount); @@ -1102,18 +1122,20 @@ int JType_ProcessClassConstructors(JNIEnv* jenv, JPy_JType* type) for (i = 0; i < constrCount; i++) { constructor = (*jenv)->GetObjectArrayElement(jenv, constructors, i); modifiers = (*jenv)->CallIntMethod(jenv, constructor, JPy_Constructor_GetModifiers_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); isPublic = (modifiers & 0x0001) != 0; isVarArg = (modifiers & 0x0080) != 0; if (isPublic) { parameterTypes = (*jenv)->CallObjectMethod(jenv, constructor, JPy_Constructor_GetParameterTypes_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); mid = (*jenv)->FromReflectedMethod(jenv, constructor); JType_ProcessMethod(jenv, type, methodKey, JPy_JTYPE_ATTR_NAME_JINIT, NULL, parameterTypes, 1, isVarArg, mid); - (*jenv)->DeleteLocalRef(jenv, parameterTypes); + JPy_DELETE_LOCAL_REF(parameterTypes); } - (*jenv)->DeleteLocalRef(jenv, constructor); + JPy_DELETE_LOCAL_REF(constructor); } - (*jenv)->DeleteLocalRef(jenv, constructors); + JPy_DELETE_LOCAL_REF(constructors); return 0; } @@ -1142,6 +1164,7 @@ int JType_ProcessClassFields(JNIEnv* jenv, JPy_JType* type) } else { fields = (*jenv)->CallObjectMethod(jenv, classRef, JPy_Class_GetDeclaredFields_MID); } + JPy_ON_JAVA_EXCEPTION_RETURN(-1); fieldCount = (*jenv)->GetArrayLength(jenv, fields); JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_ProcessClassFields: fieldCount=%d\n", fieldCount); @@ -1149,13 +1172,16 @@ int JType_ProcessClassFields(JNIEnv* jenv, JPy_JType* type) for (i = 0; i < fieldCount; i++) { field = (*jenv)->GetObjectArrayElement(jenv, fields, i); modifiers = (*jenv)->CallIntMethod(jenv, field, JPy_Field_GetModifiers_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); // see http://docs.oracle.com/javase/6/docs/api/constant-values.html#java.lang.reflect.Modifier.PUBLIC isPublic = (modifiers & 0x0001) != 0; isStatic = (modifiers & 0x0008) != 0; isFinal = (modifiers & 0x0010) != 0; if (isPublic) { fieldNameStr = (*jenv)->CallObjectMethod(jenv, field, JPy_Field_GetName_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); fieldTypeObj = (*jenv)->CallObjectMethod(jenv, field, JPy_Field_GetType_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); fid = (*jenv)->FromReflectedField(jenv, field); fieldName = (*jenv)->GetStringUTFChars(jenv, fieldNameStr, NULL); @@ -1163,17 +1189,16 @@ int JType_ProcessClassFields(JNIEnv* jenv, JPy_JType* type) JType_ProcessField(jenv, type, fieldKey, fieldName, fieldTypeObj, isStatic, isFinal, fid); (*jenv)->ReleaseStringUTFChars(jenv, fieldNameStr, fieldName); - (*jenv)->DeleteLocalRef(jenv, fieldTypeObj); - (*jenv)->DeleteLocalRef(jenv, fieldNameStr); + JPy_DELETE_LOCAL_REF(fieldTypeObj); + JPy_DELETE_LOCAL_REF(fieldNameStr); } - (*jenv)->DeleteLocalRef(jenv, field); + JPy_DELETE_LOCAL_REF(field); } - (*jenv)->DeleteLocalRef(jenv, fields); + JPy_DELETE_LOCAL_REF(fields); return 0; } -int JType_ProcessClassMethods(JNIEnv* jenv, JPy_JType* type) -{ +int JType_ProcessClassMethods(JNIEnv* jenv, JPy_JType* type) { jclass classRef; jobject methods; jobject method; @@ -1187,20 +1212,24 @@ int JType_ProcessClassMethods(JNIEnv* jenv, JPy_JType* type) jboolean isVarArg; jboolean isPublic; jboolean isBridge; - const char* methodName; + const char *methodName; jmethodID mid; - PyObject* methodKey; + PyObject *methodKey; classRef = type->classRef; methods = (*jenv)->CallObjectMethod(jenv, classRef, JPy_Class_GetMethods_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); methodCount = (*jenv)->GetArrayLength(jenv, methods); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_ProcessClassMethods: methodCount=%d\n", methodCount); for (i = 0; i < methodCount; i++) { method = (*jenv)->GetObjectArrayElement(jenv, methods, i); modifiers = (*jenv)->CallIntMethod(jenv, method, JPy_Method_GetModifiers_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); + // see http://docs.oracle.com/javase/6/docs/api/constant-values.html#java.lang.reflect.Modifier.PUBLIC isPublic = (modifiers & 0x0001) != 0; isStatic = (modifiers & 0x0008) != 0; @@ -1209,8 +1238,11 @@ int JType_ProcessClassMethods(JNIEnv* jenv, JPy_JType* type) // we exclude bridge methods; as covariant return types will result in bridge methods that cause ambiguity if (isPublic && !isBridge) { methodNameStr = (*jenv)->CallObjectMethod(jenv, method, JPy_Method_GetName_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); returnType = (*jenv)->CallObjectMethod(jenv, method, JPy_Method_GetReturnType_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); parameterTypes = (*jenv)->CallObjectMethod(jenv, method, JPy_Method_GetParameterTypes_MID); + JPy_ON_JAVA_EXCEPTION_RETURN(-1); mid = (*jenv)->FromReflectedMethod(jenv, method); methodName = (*jenv)->GetStringUTFChars(jenv, methodNameStr, NULL); @@ -1218,13 +1250,13 @@ int JType_ProcessClassMethods(JNIEnv* jenv, JPy_JType* type) JType_ProcessMethod(jenv, type, methodKey, methodName, returnType, parameterTypes, isStatic, isVarArg, mid); (*jenv)->ReleaseStringUTFChars(jenv, methodNameStr, methodName); - (*jenv)->DeleteLocalRef(jenv, parameterTypes); - (*jenv)->DeleteLocalRef(jenv, returnType); - (*jenv)->DeleteLocalRef(jenv, methodNameStr); + JPy_DELETE_LOCAL_REF(parameterTypes); + JPy_DELETE_LOCAL_REF(returnType); + JPy_DELETE_LOCAL_REF(methodNameStr); } - (*jenv)->DeleteLocalRef(jenv, method); + JPy_DELETE_LOCAL_REF(method); } - (*jenv)->DeleteLocalRef(jenv, methods); + JPy_DELETE_LOCAL_REF(methods); return 0; } @@ -1299,11 +1331,11 @@ int JType_AddFieldAttribute(JNIEnv* jenv, JPy_JType* declaringClass, PyObject* f } else if (fieldType == JPy_JString) { jstring objectRef = (*jenv)->GetStaticObjectField(jenv, declaringClass->classRef, fid); fieldValue = JPy_FromJString(jenv, objectRef); - (*jenv)->DeleteLocalRef(jenv, objectRef); + JPy_DELETE_LOCAL_REF(objectRef); } else { jobject objectRef = (*jenv)->GetStaticObjectField(jenv, declaringClass->classRef, fid); fieldValue = JPy_FromJObjectWithType(jenv, objectRef, (JPy_JType*) fieldType); - (*jenv)->DeleteLocalRef(jenv, objectRef); + JPy_DELETE_LOCAL_REF(objectRef); } PyDict_SetItem(typeDict, fieldName, fieldValue); return 0; @@ -1465,6 +1497,7 @@ JPy_ParamDescriptor* JType_CreateParamDescriptors(JNIEnv* jenv, int paramCount, paramDescriptor = paramDescriptors + i; type = JType_GetType(jenv, paramClass, JNI_FALSE); + JPy_DELETE_LOCAL_REF(paramClass); if (type == NULL) { return NULL; } @@ -1642,7 +1675,6 @@ int JType_MatchVarArgPyArgAsJObjectParam(JNIEnv* jenv, JPy_ParamDescriptor* para Py_ssize_t remaining = (argCount - idx); JPy_JType *componentType = paramDescriptor->type->componentType; - PyObject *varArgs; int minMatch = 100; int ii; @@ -1654,15 +1686,15 @@ int JType_MatchVarArgPyArgAsJObjectParam(JNIEnv* jenv, JPy_ParamDescriptor* para return 10; } - varArgs = PyTuple_GetSlice(pyArg, idx, argCount); for (ii = 0; ii < remaining; ii++) { - PyObject *unpack = PyTuple_GetItem(varArgs, ii); + PyObject *unpack = PyTuple_GetItem(pyArg, idx + ii); int matchValue = JType_MatchPyArgAsJObject(jenv, componentType, unpack); if (matchValue == 0) { return 0; } minMatch = matchValue < minMatch ? matchValue : minMatch; } + return minMatch; } @@ -1672,7 +1704,6 @@ int JType_MatchVarArgPyArgAsJStringParam(JNIEnv* jenv, JPy_ParamDescriptor* para Py_ssize_t remaining = (argCount - idx); JPy_JType *componentType = paramDescriptor->type->componentType; - PyObject *varArgs; int minMatch = 100; int ii; @@ -1684,15 +1715,15 @@ int JType_MatchVarArgPyArgAsJStringParam(JNIEnv* jenv, JPy_ParamDescriptor* para return 10; } - varArgs = PyTuple_GetSlice(pyArg, idx, argCount); for (ii = 0; ii < remaining; ii++) { - PyObject *unpack = PyTuple_GetItem(varArgs, ii); + PyObject *unpack = PyTuple_GetItem(pyArg, idx + ii); int matchValue = JType_MatchPyArgAsJStringParam(jenv, paramDescriptor, unpack); if (matchValue == 0) { return 0; } minMatch = matchValue < minMatch ? matchValue : minMatch; } + return minMatch; } @@ -1702,7 +1733,6 @@ int JType_MatchVarArgPyArgAsJPyObjectParam(JNIEnv* jenv, JPy_ParamDescriptor* pa Py_ssize_t remaining = (argCount - idx); JPy_JType *componentType = paramDescriptor->type->componentType; - PyObject *varArgs; int minMatch = 100; int ii; @@ -1714,9 +1744,8 @@ int JType_MatchVarArgPyArgAsJPyObjectParam(JNIEnv* jenv, JPy_ParamDescriptor* pa return 10; } - varArgs = PyTuple_GetSlice(pyArg, idx, argCount); for (ii = 0; ii < remaining; ii++) { - PyObject *unpack = PyTuple_GetItem(varArgs, ii); + PyObject *unpack = PyTuple_GetItem(pyArg, idx + ii); int matchValue = JType_MatchPyArgAsJPyObjectParam(jenv, paramDescriptor, unpack); if (matchValue == 0) { return 0; @@ -1732,7 +1761,6 @@ int JType_MatchVarArgPyArgAsJBooleanParam(JNIEnv *jenv, JPy_ParamDescriptor *par Py_ssize_t remaining = (argCount - idx); JPy_JType *componentType = paramDescriptor->type->componentType; - PyObject *varArgs; int minMatch = 100; int ii; @@ -1745,9 +1773,8 @@ int JType_MatchVarArgPyArgAsJBooleanParam(JNIEnv *jenv, JPy_ParamDescriptor *par return 10; } - varArgs = PyTuple_GetSlice(pyArg, idx, argCount); for (ii = 0; ii < remaining; ii++) { - PyObject *unpack = PyTuple_GetItem(varArgs, ii); + PyObject *unpack = PyTuple_GetItem(pyArg, idx + ii); int matchValue; if (PyBool_Check(unpack)) matchValue = 100; @@ -1790,7 +1817,6 @@ int JType_MatchVarArgPyArgIntType(const JPy_ParamDescriptor *paramDescriptor, Py Py_ssize_t remaining = (argCount - idx); JPy_JType *componentType = paramDescriptor->type->componentType; - PyObject *varArgs; int minMatch = 100; int ii; @@ -1803,9 +1829,8 @@ int JType_MatchVarArgPyArgIntType(const JPy_ParamDescriptor *paramDescriptor, Py return 10; } - varArgs = PyTuple_GetSlice(pyArg, idx, argCount); for (ii = 0; ii < remaining; ii++) { - PyObject *unpack = PyTuple_GetItem(varArgs, ii); + PyObject *unpack = PyTuple_GetItem(pyArg, idx + ii); int matchValue; if (JPy_IS_CLONG(unpack)) matchValue = 100; @@ -1836,7 +1861,6 @@ int JType_MatchVarArgPyArgAsFPType(const JPy_ParamDescriptor *paramDescriptor, P Py_ssize_t remaining = (argCount - idx); JPy_JType *componentType = paramDescriptor->type->componentType; - PyObject *varArgs; int minMatch = 100; int ii; @@ -1849,9 +1873,8 @@ int JType_MatchVarArgPyArgAsFPType(const JPy_ParamDescriptor *paramDescriptor, P return 10; } - varArgs = PyTuple_GetSlice(pyArg, idx, argCount); for (ii = 0; ii < remaining; ii++) { - PyObject *unpack = PyTuple_GetItem(varArgs, ii); + PyObject *unpack = PyTuple_GetItem(pyArg, idx + ii); int matchValue; if (PyFloat_Check(unpack)) matchValue = floatMatch; @@ -1899,12 +1922,14 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para pyBuffer = PyMem_New(Py_buffer, 1); if (pyBuffer == NULL) { PyErr_NoMemory(); + JPy_DECREF(pyArg); return -1; } flags = paramDescriptor->isMutable ? PyBUF_WRITABLE : PyBUF_SIMPLE; if (PyObject_GetBuffer(pyArg, pyBuffer, flags) < 0) { PyMem_Del(pyBuffer); + JPy_DECREF(pyArg); return -1; } @@ -1912,6 +1937,7 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para if (itemCount <= 0) { PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); + JPy_DECREF(pyArg); PyErr_Format(PyExc_ValueError, "illegal buffer argument: not a positive item count: %ld", itemCount); return -1; } @@ -1941,6 +1967,7 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para jArray = (*jenv)->NewDoubleArray(jenv, itemCount); itemSize = sizeof(jdouble); } else { + JPy_DECREF(pyArg); PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); PyErr_SetString(PyExc_RuntimeError, "internal error: illegal primitive Java type"); @@ -1951,6 +1978,7 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para Py_ssize_t bufferLen = pyBuffer->len; Py_ssize_t bufferItemSize = pyBuffer->itemsize; //printf("%ld, %ld, %ld, %ld\n", pyBuffer->len , pyBuffer->itemsize, itemCount, itemSize); + JPy_DECREF(pyArg); PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); PyErr_Format(PyExc_ValueError, @@ -1960,6 +1988,7 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para } if (jArray == NULL) { + JPy_DECREF(pyArg); PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); PyErr_NoMemory(); @@ -1969,6 +1998,7 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para if (!paramDescriptor->isOutput) { arrayItems = (*jenv)->GetPrimitiveArrayCritical(jenv, jArray, NULL); if (arrayItems == NULL) { + JPy_DECREF(pyArg); PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); PyErr_NoMemory(); @@ -1985,6 +2015,7 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para } else { jobject objectRef; if (JType_ConvertPythonToJavaObject(jenv, paramType, pyArg, &objectRef, JNI_FALSE) < 0) { + JPy_DECREF(pyArg); return -1; } value->l = objectRef; @@ -1993,6 +2024,8 @@ int JType_ConvertVarArgPyArgToJObjectArg(JNIEnv* jenv, JPy_ParamDescriptor* para } } + JPy_DECREF(pyArg); + return 0; } @@ -2336,7 +2369,7 @@ void JType_DisposeLocalObjectRefArg(JNIEnv* jenv, jvalue* value, void* data) jobject objectRef = value->l; if (objectRef != NULL) { JPy_DIAG_PRINT(JPy_DIAG_F_MEM, "JType_DisposeLocalObjectRefArg: objectRef=%p\n", objectRef); - (*jenv)->DeleteLocalRef(jenv, objectRef); + JPy_DELETE_LOCAL_REF(objectRef); } } @@ -2355,7 +2388,7 @@ void JType_DisposeReadOnlyBufferArg(JNIEnv* jenv, jvalue* value, void* data) PyMem_Del(pyBuffer); } if (jArray != NULL) { - (*jenv)->DeleteLocalRef(jenv, jArray); + JPy_DELETE_LOCAL_REF(jArray); } } @@ -2378,14 +2411,14 @@ void JType_DisposeWritableBufferArg(JNIEnv* jenv, jvalue* value, void* data) memcpy(pyBuffer->buf, arrayItems, pyBuffer->len); (*jenv)->ReleasePrimitiveArrayCritical(jenv, jArray, arrayItems, 0); } - (*jenv)->DeleteLocalRef(jenv, jArray); + JPy_DELETE_LOCAL_REF(jArray); PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); } else if (pyBuffer != NULL) { PyBuffer_Release(pyBuffer); PyMem_Del(pyBuffer); } else if (jArray != NULL) { - (*jenv)->DeleteLocalRef(jenv, jArray); + JPy_DELETE_LOCAL_REF(jArray); } } @@ -2492,7 +2525,7 @@ PyObject* JType_str(JPy_JType* self) utfChars = (*jenv)->GetStringUTFChars(jenv, strJObj, &isCopy); strPyObj = JPy_FROM_FORMAT("%s", utfChars); (*jenv)->ReleaseStringUTFChars(jenv, strJObj, utfChars); - (*jenv)->DeleteLocalRef(jenv, strJObj); + JPy_DELETE_LOCAL_REF(strJObj); return strPyObj; } diff --git a/src/main/c/jpy_module.c b/src/main/c/jpy_module.c index be4fa664..24a714de 100644 --- a/src/main/c/jpy_module.c +++ b/src/main/c/jpy_module.c @@ -679,6 +679,7 @@ JPy_JType* JPy_GetNonObjectJType(JNIEnv* jenv, jclass classRef) } type = JType_GetType(jenv, primClassRef, JNI_FALSE); + JPy_DELETE_LOCAL_REF(primClassRef); if (type == NULL) { return NULL; } @@ -701,7 +702,7 @@ jclass JPy_GetClass(JNIEnv* jenv, const char* name) } globalClassRef = (*jenv)->NewGlobalRef(jenv, localClassRef); - //(*jenv)->DeleteLocalRef(jenv, localClassRef); + JPy_DELETE_LOCAL_REF(localClassRef); if (globalClassRef == NULL) { PyErr_NoMemory(); return NULL; @@ -1160,7 +1161,7 @@ void JPy_HandleJavaException(JNIEnv* jenv) allocError = 1; break; } - (*jenv)->DeleteLocalRef(jenv, message); + JPy_DELETE_LOCAL_REF(message); } /* We should assemble a string based on the stack trace. */ @@ -1265,13 +1266,13 @@ void JPy_HandleJavaException(JNIEnv* jenv) PyErr_SetString(PyExc_RuntimeError, "Java VM exception occurred, but failed to allocate message text"); } - (*jenv)->DeleteLocalRef(jenv, message); + JPy_DELETE_LOCAL_REF(message); } else { PyErr_SetString(PyExc_RuntimeError, "Java VM exception occurred, no message"); } } - (*jenv)->DeleteLocalRef(jenv, error); + JPy_DELETE_LOCAL_REF(error); (*jenv)->ExceptionClear(jenv); } } diff --git a/src/main/c/jpy_module.h b/src/main/c/jpy_module.h index 507084a8..ce96959e 100644 --- a/src/main/c/jpy_module.h +++ b/src/main/c/jpy_module.h @@ -100,6 +100,9 @@ void JPy_ClearGlobalVars(JNIEnv* jenv); */ void JPy_HandleJavaException(JNIEnv* jenv); +#define JPy_DELETE_LOCAL_REF(VALUE) \ + (*jenv)->DeleteLocalRef(jenv, VALUE); \ + VALUE = NULL; #define JPy_ON_JAVA_EXCEPTION_GOTO(LABEL) \ if ((*jenv)->ExceptionCheck(jenv)) { \