changeset 560:81238ea2dbe3

Implement and use more helper functions. Improve comments.
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 06 Jan 2022 19:37:03 +0100
parents bb160a1e67d7
children c51f484387ee
files configmix/_py_helper.h configmix/_speedups.c
diffstat 2 files changed, 92 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/configmix/_py_helper.h	Thu Jan 06 18:50:09 2022 +0100
+++ b/configmix/_py_helper.h	Thu Jan 06 19:37:03 2022 +0100
@@ -13,6 +13,9 @@
 
 #if PY_VERSION_HEX < 0x030A0000
 
+/*
+ * Return a new owned reference to an object
+ */
 static inline
 PyObject *
 Py_NewRef(PyObject *obj)
@@ -22,6 +25,9 @@
 }
 
 
+/*
+ * Return a new owned reference to an object when the input can be NULL
+ */
 static inline
 PyObject *
 Py_XNewRef(PyObject *obj)
@@ -67,4 +73,74 @@
     return (obj1 != obj2);
 }
 
+
+/**
+ * Copy from source to destination and make an owned reference.
+ * Also safely clear the destination before.
+ */
+static inline
+void
+py_assign(PyObject **dest, PyObject *src)
+{
+    Py_XDECREF(*dest);
+    *dest = Py_NewRef(src);
+}
+
+
+/**
+ * Copy from source to destination and make an owned reference.
+ * Also safely clear the destination before. The source object may be NULL.
+ */
+static inline
+void
+py_assign_x(PyObject **dest, PyObject *src)
+{
+    Py_XDECREF(*dest);
+    *dest = Py_XNewRef(src);
+}
+
+
+/*
+ * Transfer from a borrowed reference to an owned one and clear the source.
+ * Also safely clear the destination before.
+ */
+static inline
+void
+py_transfer_borrowed(PyObject **dest, PyObject **src)
+{
+    Py_XDECREF(*dest);
+    *dest = Py_NewRef(*src);
+    *src = NULL;
+}
+
+
+/*
+ * Transfer from a borrowed reference to an owned one and clear the source.
+ * Also safely clear the destination before. The source object may be NULL.
+ */
+static inline
+void
+py_transfer_x_borrowed(PyObject **dest, PyObject **src)
+{
+    Py_XDECREF(*dest);
+    *dest = Py_XNewRef(*src);
+    *src = NULL;
+}
+
+
+/*
+ * Transfer ownership from a owned reference to an owned one and clear the
+ * source.
+ * Also safely clear the destination before.
+ */
+static inline
+void
+py_transfer_owned(PyObject **dest, PyObject **src)
+{
+    Py_XDECREF(*dest);
+    *dest = *src;
+    *src = NULL;
+}
+   
+
 #endif
--- a/configmix/_speedups.c	Thu Jan 06 18:50:09 2022 +0100
+++ b/configmix/_speedups.c	Thu Jan 06 19:37:03 2022 +0100
@@ -569,8 +569,7 @@
     if (tmp == NULL) {
         goto error;
     }
-    Py_DECREF(filters);
-    filters = tmp; tmp = NULL;
+    py_transfer_owned(&filters, &tmp);
 
     if (PyObject_Not(filters)) {
         py_clear_ref(&filters);
@@ -586,6 +585,7 @@
             goto error;
         }
         PyTuple_SetItem(res, 1, filters);  /* steals */
+        filters = NULL;
         return res;
     }
 
@@ -601,8 +601,7 @@
     if (tmp == NULL) {
         goto error;
     }
-    Py_DECREF(filters);
-    filters = tmp; tmp = NULL;
+    py_transfer_owned(&filters, &tmp);
 
     res = PyTuple_New(2);
     if (res == NULL) {
@@ -820,10 +819,9 @@
             goto error;
         }
         /* Unpack the result tuple */
-        tmp2 = PyTuple_GetItem(tmp, 0);   /* borrowed -- cannot fail */
-        Py_DECREF(varname);
-        varname = Py_NewRef(tmp2); tmp2 = NULL;
-        /* borrowed -- cannot fail -- want own */
+        /* borrowed -- cannot fail -- need ownership */
+        varname = Py_NewRef(PyTuple_GetItem(tmp, 0));
+        /* borrowed -- cannot fail -- want ownership */
         filters = Py_NewRef(PyTuple_GetItem(tmp, 1));
         py_clear_ref(&tmp);
 
@@ -863,7 +861,7 @@
                 goto error;
             }
             /* unpack the result */
-            /* borrowed -- but want own */
+            /* borrowed -- cannot fail -- but want ownership */
             varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0));
             cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1));
             py_clear_ref(&tmp);
@@ -953,7 +951,6 @@
     Py_ssize_t s_len;
     Py_ssize_t start, rest, end;
     PyObject *tmp;
-    PyObject *tmp2;
     PyObject *result = NULL;
     PyObject *varname = NULL;
     PyObject *varvalue = NULL;
@@ -1020,7 +1017,7 @@
                 py_clear_ref(&tmp);
                 goto error;
             }
-            py_clear_ref(&tmp);            
+            py_clear_ref(&tmp);
         }
         end = PyUnicode_Find(s, sstate->ENDTOK, start+2, s_len, 1);
         if (end == -2) {
@@ -1046,10 +1043,9 @@
             goto error;
         }
         /* Unpack the result tuple */
-        tmp2 = PyTuple_GetItem(tmp, 0);   /* borrowed -- cannot fail */
-        Py_DECREF(varname);
-        varname = Py_NewRef(tmp2); tmp2 = NULL;
-        /* borrowed -- cannot fail -- need ownership */        
+        /* borrowed -- cannot fail -- need ownership */
+        varname = Py_NewRef(PyTuple_GetItem(tmp, 0));
+        /* borrowed -- cannot fail -- need ownership */
         filters = Py_NewRef(PyTuple_GetItem(tmp, 1));
         py_clear_ref(&tmp);
 
@@ -1088,7 +1084,7 @@
                 goto error;
             }
             /* unpack the result */
-            /* borrowed -- but want own */            
+            /* borrowed -- but want own */
             varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0));
             cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1));
             py_clear_ref(&tmp);
@@ -1105,8 +1101,7 @@
         if (tmp == NULL) {
             goto error;
         }
-        Py_DECREF(varvalue);
-        varvalue = tmp; tmp = NULL;
+        py_transfer_owned(&varvalue, &tmp);
 
         py_clear_ref(&filters);
 
@@ -1117,8 +1112,7 @@
          * the whole `s` is just one expansion
          */
         if ((start == 0) && (rest == s_len)) {
-            Py_DECREF(result);
-            result = varvalue; varvalue = NULL;
+            py_transfer_owned(&result, &varvalue);
             goto success;     /* break out early */
         }
 
@@ -1151,15 +1145,14 @@
             py_clear_ref(&tmp);
             goto error;
         }
-        py_clear_ref(&tmp);        
+        py_clear_ref(&tmp);
     }
 
     tmp = PyUnicode_Join(sstate->EMPTY_STR, result);
     if (tmp == NULL) {
         goto error;
     }
-    Py_DECREF(result);
-    result = tmp; tmp = NULL;
+    py_transfer_owned(&result, &tmp);
 
 success:
     if (use_cache) {