[pypy-svn] r74184 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test

afa at codespeak.net afa at codespeak.net
Wed Apr 28 17:38:24 CEST 2010


Author: afa
Date: Wed Apr 28 17:38:23 2010
New Revision: 74184

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/include/methodobject.h
   pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_methodobject.py
Log:
Export fields of PyCFunction objects: ((PyCFunctionObject*)func)->m_ml->ml_name


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/methodobject.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/methodobject.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/methodobject.h	Wed Apr 28 17:38:23 2010
@@ -21,6 +21,13 @@
 };
 typedef struct PyMethodDef PyMethodDef;
 
+typedef struct
+{
+    PyObject_HEAD
+    PyMethodDef *m_ml; /* Description of the C function to call */
+    PyObject    *m_self; /* Passed as 'self' arg to the C func, can be NULL */
+} PyCFunctionObject;
+
 /* Flag passed to newmethodobject */
 #define METH_OLDARGS  0x0000
 #define METH_VARARGS  0x0001
@@ -42,7 +49,14 @@
 
 #define METH_COEXIST   0x0040
 
-
+/* Macros for direct access to these values. Type checks are *not*
+   done, so use with care. */
+#define PyCFunction_GET_FUNCTION(func) \
+        (((PyCFunctionObject *)func) -> m_ml -> ml_meth)
+#define PyCFunction_GET_SELF(func) \
+	(((PyCFunctionObject *)func) -> m_self)
+#define PyCFunction_GET_FLAGS(func) \
+	(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
 
 #ifdef __cplusplus
 }

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py	Wed Apr 28 17:38:23 2010
@@ -7,11 +7,12 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.function import BuiltinFunction, Method
 from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.pyobject import PyObject, from_ref, make_ref
+from pypy.module.cpyext.pyobject import (PyObject, from_ref, make_ref, make_typedescr,
+                                         Py_DecRef)
 from pypy.module.cpyext.api import (
     generic_cpy_call, cpython_api, PyObject, cpython_struct, METH_KEYWORDS,
     METH_O, CONST_STRING, METH_CLASS, METH_STATIC, METH_COEXIST, METH_NOARGS,
-    METH_VARARGS, build_type_checkers)
+    METH_VARARGS, build_type_checkers, PyObjectFields, bootstrap_function)
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.rlib.objectmodel import we_are_translated
@@ -28,6 +29,37 @@
      ('ml_doc', rffi.CCHARP),
      ])
 
+PyCFunctionObjectStruct = cpython_struct(
+    'PyCFunctionObject',
+    PyObjectFields + (
+     ('m_ml', lltype.Ptr(PyMethodDef)),
+     ('m_self', PyObject),
+     ))
+PyCFunctionObject = lltype.Ptr(PyCFunctionObjectStruct)
+
+ at bootstrap_function
+def init_methodobject(space):
+    make_typedescr(W_PyCFunctionObject.typedef,
+                   basestruct=PyCFunctionObject.TO,
+                   attach=cfunction_attach,
+                   dealloc=cfunction_dealloc)
+
+def cfunction_attach(space, py_obj, w_obj):
+    py_func = rffi.cast(PyCFunctionObject, py_obj)
+    assert isinstance(w_obj, W_PyCFunctionObject)
+    py_func.c_m_ml = w_obj.ml
+    py_func.c_m_self = make_ref(space, w_obj.w_self)
+
+ at cpython_api([PyObject], lltype.Void, external=False)
+def cfunction_dealloc(space, py_obj):
+    py_func = rffi.cast(PyCFunctionObject, py_obj)
+    Py_DecRef(space, py_func.c_m_self)
+    # standard dealloc
+    pto = py_obj.c_ob_type
+    obj_voidp = rffi.cast(rffi.VOIDP_real, py_obj)
+    generic_cpy_call(space, pto.c_tp_free, obj_voidp)
+    pto = rffi.cast(PyObject, pto)
+    Py_DecRef(space, pto)
 
 class W_PyCFunctionObject(Wrappable):
     def __init__(self, space, ml, w_self, doc=None):

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_methodobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_methodobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_methodobject.py	Wed Apr 28 17:38:23 2010
@@ -37,7 +37,8 @@
             ('isCFunction', 'METH_O',
              '''
              if(PyCFunction_Check(args)) {
-                 Py_RETURN_TRUE;
+                 PyCFunctionObject* func = (PyCFunctionObject*)args;
+                 return PyString_FromString(func->m_ml->ml_name);
              }
              else {
                  Py_RETURN_FALSE;
@@ -57,4 +58,4 @@
         assert mod.getarg_OLD() is None
         assert mod.getarg_OLD(1, 2) == (1, 2)
 
-        assert mod.isCFunction(mod.getarg_O)
+        assert mod.isCFunction(mod.getarg_O) == "getarg_O"



More information about the Pypy-commit mailing list