Author: Antonio Cuni <[email protected]>
Branch: cpyext-refactor-methodobject
Changeset: r92782:17fd1d984f1d
Date: 2017-10-17 00:47 +0200
http://bitbucket.org/pypy/pypy/changeset/17fd1d984f1d/

Log:    write a specialized function to convert args_w into a py_tuple,
        which sets directly c_ob_item[*] instead of going through the
        slowish PyTuple_SetItem

diff --git a/pypy/module/cpyext/methodobject.py 
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -16,7 +16,7 @@
 from pypy.module.cpyext.pyobject import (
     decref, from_ref, make_ref, as_pyobj, make_typedescr)
 from pypy.module.cpyext.state import State
-from pypy.module.cpyext.tupleobject import PyTuple_SetItem
+from pypy.module.cpyext.tupleobject import tuple_from_args_w
 
 PyMethodDef = cts.gettype('PyMethodDef')
 PyCFunction = cts.gettype('PyCFunction')
@@ -133,11 +133,7 @@
         state = space.fromcache(State)
         w_self = self.w_self
         func = self.ml.c_ml_meth
-        n = len(args_w)
-        py_args = state.C.PyTuple_New(n)
-        for i, w_item in enumerate(args_w):
-            py_item = make_ref(space, w_item)
-            PyTuple_SetItem(space, py_args, i, py_item)
+        py_args = tuple_from_args_w(space, args_w)
         try:
             return generic_cpy_call(space, func, w_self, py_args)
         finally:
diff --git a/pypy/module/cpyext/test/test_tupleobject.py 
b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -6,7 +6,8 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rlib.debug import FatalError
 from pypy.module.cpyext.tupleobject import (
-    PyTupleObject, PyTuple_Check, PyTuple_SetItem, PyTuple_Size)
+    PyTupleObject, PyTuple_Check, PyTuple_SetItem, PyTuple_Size,
+    tuple_from_args_w)
 from pypy.module.cpyext.state import State
 
 class TestTupleObject(BaseApiTest):
@@ -77,6 +78,16 @@
         assert py_b == py_a
         assert py_b.c_ob_pypy_link == 0
 
+    def test_tuple_from_args_w(self, space, api):
+        args_w = [space.newint(i) for i in (40, 41, 42)]
+        py_tuple = tuple_from_args_w(space, args_w)
+        assert py_tuple.c_ob_refcnt == 1
+        assert api.PyTuple_Size(py_tuple) == 3
+        py_items = [api.PyTuple_GetItem(py_tuple, i) for i in range(3)]
+        items = [api.PyInt_AsLong(py_obj) for py_obj in py_items]
+        assert items == [40, 41, 42]
+        decref(space, py_tuple)
+
     def test_tuple_resize(self, space, api):
         state = space.fromcache(State)
         w_42 = space.wrap(42)
diff --git a/pypy/module/cpyext/tupleobject.py 
b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -113,6 +113,14 @@
     track_reference(space, py_obj, w_obj)
     return w_obj
 
+def tuple_from_args_w(space, args_w):
+    state = space.fromcache(State)
+    n = len(args_w)
+    py_tuple = state.C.PyTuple_New(n) # XXX: check for errors?
+    py_tuple = rffi.cast(PyTupleObject, py_tuple)
+    for i, w_obj in enumerate(args_w):
+        py_tuple.c_ob_item[i] = make_ref(space, w_obj)
+    return rffi.cast(PyObject, py_tuple)
 
 @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
 def PyTuple_SetItem(space, ref, index, py_obj):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to