Author: mattip <[email protected]>
Branch: cpyext-ext
Changeset: r83056:731fbe0846a6
Date: 2016-03-14 22:12 +0200
http://bitbucket.org/pypy/pypy/changeset/731fbe0846a6/

Log:    refactor PyStringObject to use PyObject_VARHEAD not PyObject_HEAD,
        improve failing test

diff --git a/pypy/module/cpyext/bytesobject.py 
b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -27,7 +27,7 @@
 ## Solution
 ## --------
 ##
-## PyStringObject contains two additional members: the size and a pointer to a
+## PyStringObject contains two additional members: the ob_size and a pointer 
to a
 ## char buffer; it may be NULL.
 ##
 ## - A string allocated by pypy will be converted into a PyStringObject with a
@@ -36,7 +36,7 @@
 ##
 ## - A string allocated with PyString_FromStringAndSize(NULL, size) will
 ##   allocate a PyStringObject structure, and a buffer with the specified
-##   size, but the reference won't be stored in the global map; there is no
+##   size+1, but the reference won't be stored in the global map; there is no
 ##   corresponding object in pypy.  When from_ref() or Py_INCREF() is called,
 ##   the pypy string is created, and added to the global map of tracked
 ##   objects.  The buffer is then supposed to be immutable.
@@ -54,7 +54,7 @@
 PyStringObject = lltype.Ptr(PyStringObjectStruct)
 PyStringObjectFields = PyObjectFields + \
     (("ob_shash", rffi.LONG), ("ob_sstate", rffi.INT), 
-     ("buffer", rffi.CCHARP), ("size", Py_ssize_t))
+     ("buffer", rffi.CCHARP), ("ob_size", Py_ssize_t))
 cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct)
 
 @bootstrap_function
@@ -62,7 +62,7 @@
     "Type description of PyStringObject"
     make_typedescr(space.w_str.layout.typedef,
                    basestruct=PyStringObject.TO,
-                   alloc = string_alloc,
+                   #alloc = string_alloc,
                    attach=string_attach,
                    dealloc=string_dealloc,
                    realize=string_realize)
@@ -77,6 +77,7 @@
     from string_attach. This is used as the tp_alloc function
     for PyStringObject
     '''
+    xxxx # TODO remove
     from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
     pytype = as_pyobj(space, w_type)
     pytype = rffi.cast(PyTypeObjectPtr, pytype)
@@ -90,7 +91,7 @@
     if length > 0:
         py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, length+1,
                                         flavor='raw', zero=True)
-        py_str.c_size = length
+        py_str.c_ob_size = length
         py_str.c_ob_sstate = rffi.cast(rffi.INT, 0) # SSTATE_NOT_INTERNED
         s = rffi.charpsize2str(py_str.c_buffer, length+1)
         w_obj = space.wrap(s)
@@ -110,7 +111,7 @@
     py_str = rffi.cast(PyStringObject, py_obj)
 
     buflen = length + 1
-    py_str.c_size = length
+    py_str.c_ob_size = length
     py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen,
                                     flavor='raw', zero=True)
     py_str.c_ob_sstate = rffi.cast(rffi.INT, 0) # SSTATE_NOT_INTERNED
@@ -122,7 +123,7 @@
     buffer must not be modified.
     """
     py_str = rffi.cast(PyStringObject, py_obj)
-    py_str.c_size = len(space.str_w(w_obj))
+    py_str.c_ob_size = len(space.str_w(w_obj))
     py_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
     py_str.c_ob_shash = space.hash_w(w_obj)
     py_str.c_ob_sstate = rffi.cast(rffi.INT, 1) # SSTATE_INTERNED_MORTAL
@@ -133,7 +134,7 @@
     be modified after this call.
     """
     py_str = rffi.cast(PyStringObject, py_obj)
-    s = rffi.charpsize2str(py_str.c_buffer, py_str.c_size)
+    s = rffi.charpsize2str(py_str.c_buffer, py_str.c_ob_size)
     w_obj = space.wrap(s)
     py_str.c_ob_shash = space.hash_w(w_obj)
     py_str.c_ob_sstate = rffi.cast(rffi.INT, 1) # SSTATE_INTERNED_MORTAL
@@ -193,12 +194,12 @@
         ref_str.c_buffer = rffi.str2charp(s)
     buffer[0] = ref_str.c_buffer
     if length:
-        length[0] = ref_str.c_size
+        length[0] = ref_str.c_ob_size
     else:
         i = 0
         while ref_str.c_buffer[i] != '\0':
             i += 1
-        if i != ref_str.c_size:
+        if i != ref_str.c_ob_size:
             raise OperationError(space.w_TypeError, space.wrap(
                 "expected string without null bytes"))
     return 0
@@ -207,7 +208,7 @@
 def PyString_Size(space, ref):
     if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
         ref = rffi.cast(PyStringObject, ref)
-        return ref.c_size
+        return ref.c_ob_size
     else:
         w_obj = from_ref(space, ref)
         return space.len_w(w_obj)
@@ -236,7 +237,7 @@
         ref[0] = lltype.nullptr(PyObject.TO)
         raise
     to_cp = newsize
-    oldsize = py_str.c_size
+    oldsize = py_str.c_ob_size
     if oldsize < newsize:
         to_cp = oldsize
     for i in range(to_cp):
diff --git a/pypy/module/cpyext/include/stringobject.h 
b/pypy/module/cpyext/include/stringobject.h
--- a/pypy/module/cpyext/include/stringobject.h
+++ b/pypy/module/cpyext/include/stringobject.h
@@ -38,15 +38,15 @@
 
 
 typedef struct {
-    PyObject_HEAD
+    PyObject_VAR_HEAD
     long ob_shash;
     int ob_sstate;
-    char * buffer;
-    Py_ssize_t size;
+    char * buffer; /* change the name from cpython so all non-api c access is 
thwarted */
 
-    /* Invariants:
-     *     ob_sval contains space for 'ob_size+1' elements.
-     *     ob_sval[ob_size] == 0.
+    /* Invariants 
+     * (not relevant in PyPy, all stringobjects are backed by a pypy object)
+     *     buffer contains space for 'ob_size+1' elements.
+     *     buffer[ob_size] == 0.
      *     ob_shash is the hash of the string or -1 if not computed yet.
      *     ob_sstate != 0 iff the string object is in stringobject.c's
      *       'interned' dictionary; in this case the two references
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -91,13 +91,15 @@
 
     def test_string_tp_alloc(self):
         module = self.import_extension('foo', [
-            ("getstring", "METH_NOARGS",
+            ("tpalloc", "METH_NOARGS",
              """
                 PyObject *base;
                 PyTypeObject * type;
                 PyStringObject *obj;
                 char * p_str;
                 base = PyString_FromString("test");
+                if (((PyStringObject*)base)->buffer == NULL)
+                    return PyLong_FromLong(-2);
                 type = base->ob_type;
                 if (type->tp_itemsize != 1)
                     return PyLong_FromLong(type->tp_itemsize);
@@ -109,7 +111,7 @@
                 return (PyObject*)obj;
              """),
             ])
-        s = module.getstring()
+        s = module.tpalloc()
         assert s == 'works\x00\x00\x00\x00\x00'
 
     def test_AsString(self):
@@ -262,14 +264,14 @@
         ar[0] = rffi.cast(PyObject, py_str)
         api._PyString_Resize(ar, 3)
         py_str = rffi.cast(PyStringObject, ar[0])
-        assert py_str.c_size == 3
+        assert py_str.c_ob_size == 3
         assert py_str.c_buffer[1] == 'b'
         assert py_str.c_buffer[3] == '\x00'
         # the same for growing
         ar[0] = rffi.cast(PyObject, py_str)
         api._PyString_Resize(ar, 10)
         py_str = rffi.cast(PyStringObject, ar[0])
-        assert py_str.c_size == 10
+        assert py_str.c_ob_size == 10
         assert py_str.c_buffer[1] == 'b'
         assert py_str.c_buffer[10] == '\x00'
         Py_DecRef(space, ar[0])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to