Skip to content

Commit 7f93a04

Browse files
committed
Disallow using "bare" PyObject arg behavior for C API functions returns
1 parent 9b41424 commit 7f93a04

File tree

4 files changed

+22
-7
lines changed

4 files changed

+22
-7
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer;
5757
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyThreadState;
5858
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObject;
59+
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObjectTransfer;
5960
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t;
6061
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.SIZE_T;
6162
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.UINTPTR_T;
@@ -918,7 +919,7 @@ static TruffleString encoding() {
918919
}
919920
}
920921

921-
@CApiBuiltin(ret = PyTypeObject, args = {ConstCharPtrAsTruffleString}, call = Ignored)
922+
@CApiBuiltin(ret = PyTypeObjectTransfer, args = {ConstCharPtrAsTruffleString}, call = Ignored)
922923
abstract static class PyTruffle_Type extends CApiUnaryBuiltinNode {
923924

924925
private static final TruffleString[] LOOKUP_MODULES = new TruffleString[]{

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PySliceObject;
7070
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTupleObject;
7171
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObject;
72+
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObjectBorrowed;
7273
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyUnicodeObject;
7374
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyVarObject;
7475
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t;
@@ -271,7 +272,7 @@ static Object get(Object object,
271272
}
272273
}
273274

274-
@CApiBuiltin(ret = PyTypeObject, args = {PyCMethodObject}, call = Ignored)
275+
@CApiBuiltin(ret = PyTypeObjectBorrowed, args = {PyCMethodObject}, call = Ignored)
275276
abstract static class Py_get_PyCMethodObject_mm_class extends CApiUnaryBuiltinNode {
276277
@Specialization
277278
static Object get(PBuiltinMethod object) {
@@ -388,7 +389,7 @@ static Object get(GetSetDescriptor object) {
388389
}
389390
}
390391

391-
@CApiBuiltin(ret = PyTypeObject, args = {PyDescrObject}, call = Ignored)
392+
@CApiBuiltin(ret = PyTypeObjectBorrowed, args = {PyDescrObject}, call = Ignored)
392393
abstract static class Py_get_PyDescrObject_d_type extends CApiUnaryBuiltinNode {
393394

394395
@Specialization
@@ -682,7 +683,7 @@ static Object get(PythonAbstractObjectNativeWrapper wrapper) {
682683
}
683684
}
684685

685-
@CApiBuiltin(ret = PyTypeObject, args = {PyObject}, call = Ignored)
686+
@CApiBuiltin(ret = PyTypeObjectBorrowed, args = {PyObject}, call = Ignored)
686687
abstract static class Py_get_PyObject_ob_type extends CApiUnaryBuiltinNode {
687688

688689
@Specialization
@@ -711,23 +712,23 @@ static long get(PBaseSet object,
711712
}
712713
}
713714

714-
@CApiBuiltin(ret = PyObject, args = {PySliceObject}, call = Ignored)
715+
@CApiBuiltin(ret = PyObjectBorrowed, args = {PySliceObject}, call = Ignored)
715716
abstract static class Py_get_PySliceObject_start extends CApiUnaryBuiltinNode {
716717
@Specialization
717718
static Object doStart(PSlice object) {
718719
return object.getStart();
719720
}
720721
}
721722

722-
@CApiBuiltin(ret = PyObject, args = {PySliceObject}, call = Ignored)
723+
@CApiBuiltin(ret = PyObjectBorrowed, args = {PySliceObject}, call = Ignored)
723724
abstract static class Py_get_PySliceObject_step extends CApiUnaryBuiltinNode {
724725
@Specialization
725726
static Object doStep(PSlice object) {
726727
return object.getStep();
727728
}
728729
}
729730

730-
@CApiBuiltin(ret = PyObject, args = {PySliceObject}, call = Ignored)
731+
@CApiBuiltin(ret = PyObjectBorrowed, args = {PySliceObject}, call = Ignored)
731732
abstract static class Py_get_PySliceObject_stop extends CApiUnaryBuiltinNode {
732733
@Specialization
733734
static Object doStop(PSlice object) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,10 @@ private static void addCApiBuiltins(List<CApiBuiltinDesc> result, Class<?> conta
14721472
if (!annotation.name().isEmpty()) {
14731473
name = annotation.name();
14741474
}
1475+
if (!annotation.ret().isValidReturnType()) {
1476+
throw new IllegalArgumentException(
1477+
String.format("Invalid @CApiBuiltin %s: %s is not an allowed return type, use PyObjectTransfer or PyObjectBorrow variants", name, annotation.ret()));
1478+
}
14751479
Class<?> gen;
14761480
try {
14771481
gen = Class.forName(container.getName() + "Factory$" + clazz.getSimpleName() + "NodeGen");

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public enum ArgDescriptor {
120120
PyObjectWrapper(ArgBehavior.PyObjectWrapper, "PyObject*"),
121121
PyObjectAsTruffleString(ArgBehavior.PyObjectAsTruffleString, "PyObject*"),
122122
PyTypeObject(ArgBehavior.PyObject, "PyTypeObject*"),
123+
PyTypeObjectBorrowed(ArgBehavior.PyObjectBorrowed, "PyTypeObject*"),
123124
PyTypeObjectTransfer(ArgBehavior.PyObject, "PyTypeObject*", true),
124125
PyListObject(ArgBehavior.PyObject, "PyListObject*"),
125126
PyTupleObject(ArgBehavior.PyObject, "PyTupleObject*"),
@@ -430,6 +431,14 @@ public boolean isPyObject() {
430431
return behavior == ArgBehavior.PyObject || behavior == ArgBehavior.PyObjectBorrowed;
431432
}
432433

434+
public boolean isValidReturnType() {
435+
/*
436+
* We don't want to allow "bare" PyObject and force ourselves to decide between
437+
* PyObjectTransfer and PyObjectBorrow
438+
*/
439+
return behavior != ArgBehavior.PyObject || transfer;
440+
}
441+
433442
public boolean isCharPtr() {
434443
return this == CharPtrAsTruffleString || this == CHAR_PTR || this == ConstCharPtr || this == ConstCharPtrAsTruffleString;
435444
}

0 commit comments

Comments
 (0)