[pypy-commit] pypy cpyext-ext: define/modify for upstream compatibity PyMem_Malloc, PyStringObject, _Py_HashDouble
mattip
noreply at buildbot.pypy.org
Thu Nov 26 18:55:14 EST 2015
Author: mattip <matti.picus at gmail.com>
Branch: cpyext-ext
Changeset: r80981:c114f7d51108
Date: 2015-11-27 01:55 +0200
http://bitbucket.org/pypy/pypy/changeset/c114f7d51108/
Log: define/modify for upstream compatibity PyMem_Malloc, PyStringObject,
_Py_HashDouble
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -1056,6 +1056,7 @@
source_dir / "pythread.c",
source_dir / "ndarrayobject.c",
source_dir / "missing.c",
+ source_dir / "pymem.c",
],
separate_module_sources=separate_module_sources,
compile_extra=compile_extra,
diff --git a/pypy/module/cpyext/include/pymem.h b/pypy/module/cpyext/include/pymem.h
--- a/pypy/module/cpyext/include/pymem.h
+++ b/pypy/module/cpyext/include/pymem.h
@@ -5,7 +5,7 @@
#define PyMem_REALLOC(p, n) realloc((p), (n) ? (n) : 1)
#define PyMem_FREE free
-#define PyMem_Malloc PyMem_MALLOC
+void * PyMem_Malloc(size_t);
#define PyMem_Free PyMem_FREE
#define PyMem_Realloc PyMem_REALLOC
diff --git a/pypy/module/cpyext/include/pyport.h b/pypy/module/cpyext/include/pyport.h
--- a/pypy/module/cpyext/include/pyport.h
+++ b/pypy/module/cpyext/include/pyport.h
@@ -64,6 +64,14 @@
# error "Python needs a typedef for Py_uintptr_t in pyport.h."
#endif /* HAVE_UINTPTR_T */
+/* Py_hash_t is the same size as a pointer. */
+#define SIZEOF_PY_HASH_T SIZEOF_SIZE_T
+typedef Py_ssize_t Py_hash_t;
+/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */
+#define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T
+typedef size_t Py_uhash_t;
+
+
/*******************************
* stat() and fstat() fiddling *
*******************************/
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
@@ -7,15 +7,59 @@
extern "C" {
#endif
+#include <stdarg.h>
+
+/*
+Type PyStringObject represents a character string. An extra zero byte is
+reserved at the end to ensure it is zero-terminated, but a size is
+present so strings with null bytes in them can be represented. This
+is an immutable object type.
+
+There are functions to create new string objects, to test
+an object for string-ness, and to get the
+string value. The latter function returns a null pointer
+if the object is not of the proper type.
+There is a variant that takes an explicit size as well as a
+variant that assumes a zero-terminated string. Note that none of the
+functions should be applied to nil objects.
+*/
+
+/* Caching the hash (ob_shash) saves recalculation of a string's hash value.
+ Interning strings (ob_sstate) tries to ensure that only one string
+ object with a given value exists, so equality tests can be one pointer
+ comparison. This is generally restricted to strings that "look like"
+ Python identifiers, although the intern() builtin can be used to force
+ interning of any string.
+ Together, these sped cpython up by up to 20%, and since they are part of the
+ "public" interface PyPy must reimpliment them. */
+
+
#define PyString_GET_SIZE(op) PyString_Size(op)
#define PyString_AS_STRING(op) PyString_AsString(op)
typedef struct {
PyObject_HEAD
- char* buffer;
+ long ob_shash;
+ int ob_sstate;
+ char * buffer;
Py_ssize_t size;
+
+ /* Invariants:
+ * ob_sval contains space for 'ob_size+1' elements.
+ * ob_sval[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
+ * from 'interned' to this object are *not counted* in ob_refcnt.
+ */
+
} PyStringObject;
+#define SSTATE_NOT_INTERNED 0
+#define SSTATE_INTERNED_MORTAL 1
+#define SSTATE_INTERNED_IMMORTAL 2
+#define PyString_CHECK_INTERNED(op) (((PyStringObject *)(op))->ob_sstate)
+
PyAPI_FUNC(PyObject *) PyString_FromFormatV(const char *format, va_list vargs);
PyAPI_FUNC(PyObject *) PyString_FromFormat(const char *format, ...);
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -387,6 +387,11 @@
This is the equivalent of the Python expression hash(o)."""
return space.int_w(space.hash(w_obj))
+ at cpython_api([rffi.LONG], rffi.DOUBLE, error=-1)
+def _Py_HashDouble(space, w_obj):
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap("_Py_HashDouble not implemented yet"))
+
@cpython_api([PyObject], lltype.Signed, error=-1)
def PyObject_HashNotImplemented(space, o):
"""Set a TypeError indicating that type(o) is not hashable and return -1.
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -53,7 +53,8 @@
PyStringObjectStruct = lltype.ForwardReference()
PyStringObject = lltype.Ptr(PyStringObjectStruct)
PyStringObjectFields = PyObjectFields + \
- (("buffer", rffi.CCHARP), ("size", Py_ssize_t))
+ (("ob_shash", rffi.LONG), ("ob_sstate", rffi.INT),
+ ("buffer", rffi.CCHARP), ("size", Py_ssize_t))
cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct)
@bootstrap_function
@@ -81,6 +82,7 @@
py_str.c_size = length
py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen,
flavor='raw', zero=True)
+ py_str.c_ob_sstate = 0 # SSTATE_NOT_INTERNED
return py_str
def string_attach(space, py_obj, w_obj):
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -173,6 +173,9 @@
api.PyErr_Occurred() is space.w_TypeError)
api.PyErr_Clear()
+ def test_hash_double(self, space, api):
+ assert False
+
def test_type(self, space, api):
assert api.PyObject_Type(space.wrap(72)) is space.w_int
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_stringobject.py
@@ -189,6 +189,10 @@
# This does not test much, but at least the refcounts are checked.
assert module.test_intern_inplace('s') == 's'
+ def test_hash_and_state(self):
+ # XXX write tests for ob_shash and ob_sstate
+ assert False
+
class TestString(BaseApiTest):
def test_string_resize(self, space, api):
py_str = new_empty_str(space, 10)
More information about the pypy-commit
mailing list