Author: Jean-Paul Calderone <[email protected]>
Branch: safe-getargs-freelist
Changeset: r53716:0b8690130dac
Date: 2012-03-16 09:21 -0400
http://bitbucket.org/pypy/pypy/changeset/0b8690130dac/

Log:    Stack allocate the freelist structure, since it can never escape.
        Copy some other style fixes based on review of the patch for
        cpython.

diff --git a/pypy/module/cpyext/src/getargs.c b/pypy/module/cpyext/src/getargs.c
--- a/pypy/module/cpyext/src/getargs.c
+++ b/pypy/module/cpyext/src/getargs.c
@@ -30,14 +30,12 @@
    which will need to be deallocated or cleaned up somehow if overall
    parsing fails.
 */
-typedef struct _Py_CleanupFreelistEntry
-{
+typedef struct {
   void *item;
   destr_t destructor;
 } freelistentry_t;
 
-typedef struct _Py_CleanupFreelist
-{
+typedef struct {
   int first_available;
   freelistentry_t *entries;
 } freelist_t;
@@ -186,18 +184,16 @@
 {
     int index;
 
-    if (retval == 0)
-    {
+    if (retval == 0) {
       /* A failure occurred, therefore execute all of the cleanup
         functions.
       */
-      for (index = 0; index < freelist->first_available; ++index)
-      {
-          freelist->entries[index].destructor(NULL, 
freelist->entries[index].item);
+      for (index = 0; index < freelist->first_available; ++index) {
+          freelist->entries[index].destructor(NULL,
+                                              freelist->entries[index].item);
       }
     }
     PyMem_Free(freelist->entries);
-    PyMem_Free(freelist);
     return retval;
 }
 
@@ -215,7 +211,7 @@
        const char *formatsave = format;
        Py_ssize_t i, len;
        char *msg;
-       freelist_t *freelist;
+       freelist_t freelist = {0, NULL};
        int compat = flags & FLAG_COMPAT;
 
        assert(compat || (args != (PyObject*)NULL));
@@ -271,20 +267,18 @@
        
        format = formatsave;
        
-       freelist = PyMem_New(freelist_t, 1);
-       freelist->first_available = 0;
-       freelist->entries = PyMem_New(freelistentry_t, max);
+       freelist.entries = PyMem_New(freelistentry_t, max);
 
        if (compat) {
                if (max == 0) {
                        if (args == NULL)
-                           return cleanreturn(1, freelist);
+                           return cleanreturn(1, &freelist);
                        PyOS_snprintf(msgbuf, sizeof(msgbuf),
                                      "%.200s%s takes no arguments",
                                      fname==NULL ? "function" : fname,
                                      fname==NULL ? "" : "()");
                        PyErr_SetString(PyExc_TypeError, msgbuf);
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
                else if (min == 1 && max == 1) {
                        if (args == NULL) {
@@ -293,26 +287,26 @@
                                              fname==NULL ? "function" : fname,
                                              fname==NULL ? "" : "()");
                                PyErr_SetString(PyExc_TypeError, msgbuf);
-                               return cleanreturn(0, freelist);
+                               return cleanreturn(0, &freelist);
                        }
                        msg = convertitem(args, &format, p_va, flags, levels, 
-                                         msgbuf, sizeof(msgbuf), freelist);
+                                         msgbuf, sizeof(msgbuf), &freelist);
                        if (msg == NULL)
-                               return cleanreturn(1, freelist);
+                               return cleanreturn(1, &freelist);
                        seterror(levels[0], msg, levels+1, fname, message);
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
                else {
                        PyErr_SetString(PyExc_SystemError,
                            "old style getargs format uses new features");
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
        }
        
        if (!PyTuple_Check(args)) {
                PyErr_SetString(PyExc_SystemError,
                    "new style getargs format but argument is not a tuple");
-               return cleanreturn(0, freelist);
+               return cleanreturn(0, &freelist);
        }
        
        len = PyTuple_GET_SIZE(args);
@@ -332,7 +326,7 @@
                        message = msgbuf;
                }
                PyErr_SetString(PyExc_TypeError, message);
-               return cleanreturn(0, freelist);
+               return cleanreturn(0, &freelist);
        }
        
        for (i = 0; i < len; i++) {
@@ -340,10 +334,10 @@
                        format++;
                msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
                                  flags, levels, msgbuf, 
-                                 sizeof(msgbuf), freelist);
+                                 sizeof(msgbuf), &freelist);
                if (msg) {
                        seterror(i+1, msg, levels, fname, message);
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
        }
 
@@ -352,10 +346,10 @@
            *format != '|' && *format != ':' && *format != ';') {
                PyErr_Format(PyExc_SystemError,
                             "bad format string: %.200s", formatsave);
-               return cleanreturn(0, freelist);
+               return cleanreturn(0, &freelist);
        }
        
-       return cleanreturn(1, freelist);
+       return cleanreturn(1, &freelist);
 }
 
 
@@ -1526,7 +1520,7 @@
        int min = INT_MAX;
        int i, len, nargs, nkeywords;
        PyObject *current_arg;
-       freelist_t *freelist;
+       freelist_t freelist = {0, NULL};
 
 
        assert(args != NULL && PyTuple_Check(args));
@@ -1551,9 +1545,7 @@
        for (len=0; kwlist[len]; len++)
                continue;
 
-       freelist = PyMem_New(freelist_t, 1);
-       freelist->first_available = 0;
-       freelist->entries = PyMem_New(freelistentry_t, len);
+       freelist.entries = PyMem_New(freelistentry_t, len);
 
        nargs = PyTuple_GET_SIZE(args);
        nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
@@ -1565,7 +1557,7 @@
                             len,
                             (len == 1) ? "" : "s",
                             nargs + nkeywords);
-               return cleanreturn(0, freelist);
+               return cleanreturn(0, &freelist);
        }
 
        /* convert tuple args and keyword args in same loop, using kwlist to 
drive process */
@@ -1579,7 +1571,7 @@
                        PyErr_Format(PyExc_RuntimeError,
                                     "More keyword list entries (%d) than "
                                     "format specifiers (%d)", len, i);
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
                current_arg = NULL;
                if (nkeywords) {
@@ -1593,20 +1585,20 @@
                                             "Argument given by name ('%s') "
                                             "and position (%d)",
                                             keyword, i+1);
-                               return cleanreturn(0, freelist);
+                               return cleanreturn(0, &freelist);
                        }
                }
                else if (nkeywords && PyErr_Occurred())
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                else if (i < nargs)
                        current_arg = PyTuple_GET_ITEM(args, i);
                        
                if (current_arg) {
                        msg = convertitem(current_arg, &format, p_va, flags,
-                               levels, msgbuf, sizeof(msgbuf), freelist);
+                               levels, msgbuf, sizeof(msgbuf), &freelist);
                        if (msg) {
                                seterror(i+1, msg, levels, fname, custom_msg);
-                               return cleanreturn(0, freelist);
+                               return cleanreturn(0, &freelist);
                        }
                        continue;
                }
@@ -1615,14 +1607,14 @@
                        PyErr_Format(PyExc_TypeError, "Required argument "
                                     "'%s' (pos %d) not found",
                                     keyword, i+1);
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
                /* current code reports success when all required args
                 * fulfilled and no keyword args left, with no further
                 * validation. XXX Maybe skip this in debug build ?
                 */
                if (!nkeywords)
-                       return cleanreturn(1, freelist);
+                       return cleanreturn(1, &freelist);
 
                /* We are into optional args, skip thru to any remaining
                 * keyword args */
@@ -1630,7 +1622,7 @@
                if (msg) {
                        PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
                                     format);
-                       return cleanreturn(0, freelist);
+                       return cleanreturn(0, &freelist);
                }
        }
 
@@ -1638,7 +1630,7 @@
                PyErr_Format(PyExc_RuntimeError,
                        "more argument specifiers than keyword list entries "
                        "(remaining format:'%s')", format);
-               return cleanreturn(0, freelist);
+               return cleanreturn(0, &freelist);
        }
 
        /* make sure there are no extraneous keyword arguments */
@@ -1651,7 +1643,7 @@
                        if (!PyString_Check(key)) {
                             PyErr_SetString(PyExc_TypeError, 
                                                "keywords must be strings");
-                               return cleanreturn(0, freelist);
+                               return cleanreturn(0, &freelist);
                        }
                        ks = PyString_AsString(key);
                        for (i = 0; i < len; i++) {
@@ -1665,12 +1657,12 @@
                                             "'%s' is an invalid keyword "
                                             "argument for this function",
                                             ks);
-                               return cleanreturn(0, freelist);
+                               return cleanreturn(0, &freelist);
                        }
                }
        }
 
-       return cleanreturn(1, freelist);
+       return cleanreturn(1, &freelist);
 }
 
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to