Skip to content

Commit 432c5fc

Browse files
committed
[bugfix] Release JNI buffers after primitive array conversion (#102)
1 parent 4192899 commit 432c5fc

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

‎src/main/c/pemja/core/pyutils.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ JcpAPI_FUNC(PyObject*)
631631
PyTuple_SetItem(result, i, JcpPyBool_FromLong(booleans[i]));
632632
}
633633

634+
(*env)->ReleaseBooleanArrayElements(env, value, booleans, JNI_ABORT);
634635
return result;
635636
}
636637

@@ -653,6 +654,7 @@ JcpAPI_FUNC(PyObject*)
653654
PyTuple_SetItem(result, i, JcpPyInt_FromInt(shorts[i]));
654655
}
655656

657+
(*env)->ReleaseShortArrayElements(env, value, shorts, JNI_ABORT);
656658
return result;
657659
}
658660

@@ -674,6 +676,7 @@ JcpAPI_FUNC(PyObject*) JcpPyTuple_FromJIntArray(JNIEnv* env, jintArray value) {
674676
PyTuple_SetItem(result, i, JcpPyInt_FromInt(ints[i]));
675677
}
676678

679+
(*env)->ReleaseIntArrayElements(env, value, ints, JNI_ABORT);
677680
return result;
678681
}
679682

@@ -696,6 +699,7 @@ JcpAPI_FUNC(PyObject*)
696699
PyTuple_SetItem(result, i, JcpPyInt_FromLong(longs[i]));
697700
}
698701

702+
(*env)->ReleaseLongArrayElements(env, value, longs, JNI_ABORT);
699703
return result;
700704
}
701705

@@ -718,6 +722,7 @@ JcpAPI_FUNC(PyObject*)
718722
PyTuple_SetItem(result, i, JcpPyFloat_FromDouble(floats[i]));
719723
}
720724

725+
(*env)->ReleaseFloatArrayElements(env, value, floats, JNI_ABORT);
721726
return result;
722727
}
723728

@@ -740,6 +745,7 @@ JcpAPI_FUNC(PyObject*)
740745
PyTuple_SetItem(result, i, JcpPyFloat_FromDouble(doubles[i]));
741746
}
742747

748+
(*env)->ReleaseDoubleArrayElements(env, value, doubles, JNI_ABORT);
743749
return result;
744750
}
745751

‎src/test/java/pemja/core/PythonInterpreterTest.java‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.io.File;
2626
import java.io.FileNotFoundException;
2727
import java.io.IOException;
28+
import java.lang.reflect.Array;
2829
import java.math.BigDecimal;
2930
import java.math.BigInteger;
3031
import java.nio.file.Files;
@@ -247,6 +248,35 @@ public void testCallPython() {
247248
}
248249
}
249250

251+
@Test
252+
public void testInvokeMethodWithPrimitiveArrays() {
253+
PythonInterpreterConfig config =
254+
PythonInterpreterConfig.newBuilder().addPythonPaths(testDir).build();
255+
try (PythonInterpreter interpreter = new PythonInterpreter(config)) {
256+
interpreter.exec("import test_call");
257+
Object[][] cases = {
258+
{new boolean[] {true, false}, new Object[] {true, false}},
259+
{new short[] {1, 2}, new Object[] {1L, 2L}},
260+
{new int[] {1, 2}, new Object[] {1L, 2L}},
261+
{new long[] {1, 2}, new Object[] {1L, 2L}},
262+
{new float[] {1.5f, 2.5f}, new Object[] {1.5d, 2.5d}},
263+
{new double[] {1.5, 2.5}, new Object[] {1.5d, 2.5d}}
264+
};
265+
for (Object[] testCase : cases) {
266+
Object array = testCase[0];
267+
assertArrayEquals(
268+
(Object[]) testCase[1],
269+
(Object[])
270+
interpreter.invokeMethod("test_call", "test_call_one_arg", array));
271+
Object empty = Array.newInstance(array.getClass().getComponentType(), 0);
272+
assertArrayEquals(
273+
new Object[0],
274+
(Object[])
275+
interpreter.invokeMethod("test_call", "test_call_one_arg", empty));
276+
}
277+
}
278+
}
279+
250280
@Test
251281
public void testCallPythonWithAllTypes() throws Exception {
252282
PythonInterpreterConfig config =

0 commit comments

Comments
 (0)