Author: Armin Rigo <ar...@tunes.org>
Branch: share-cpyext-cpython-api
Changeset: r84056:e4d93f6ca982
Date: 2016-04-30 12:11 +0100
http://bitbucket.org/pypy/pypy/changeset/e4d93f6ca982/

Log:    mess in progress

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
@@ -256,7 +256,7 @@
 
 class ApiFunction:
     def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
-                 c_name=None, gil=None, result_borrowed=False):
+                 c_name=None, gil=None, result_borrowed=False, 
result_is_ll=False):
         self.argtypes = argtypes
         self.restype = restype
         self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
@@ -277,6 +277,9 @@
         assert len(self.argnames) == len(self.argtypes)
         self.gil = gil
         self.result_borrowed = result_borrowed
+        self.result_is_ll = result_is_ll
+        if result_is_ll:    # means 'returns a low-level PyObject pointer'
+            assert is_PyObject(restype)
         #
         def get_llhelper(space):
             return llhelper(self.functype, self.get_wrapper(space))
@@ -298,7 +301,7 @@
 
 DEFAULT_HEADER = 'pypy_decl.h'
 def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER,
-                gil=None, result_borrowed=False):
+                gil=None, result_borrowed=False, result_is_ll=False):
     """
     Declares a function to be exported.
     - `argtypes`, `restype` are lltypes and describe the function signature.
@@ -337,7 +340,8 @@
             c_name = func_name
         api_function = ApiFunction(argtypes, restype, func, error,
                                    c_name=c_name, gil=gil,
-                                   result_borrowed=result_borrowed)
+                                   result_borrowed=result_borrowed,
+                                   result_is_ll=result_is_ll)
         func.api_func = api_function
 
         if error is _NOT_SPECIFIED:
@@ -613,6 +617,9 @@
 def is_PyObject(TYPE):
     if not isinstance(TYPE, lltype.Ptr):
         return False
+    if TYPE == PyObject:
+        return True
+    assert not isinstance(TYPE.TO, lltype.ForwardReference)
     return hasattr(TYPE.TO, 'c_ob_refcnt') and hasattr(TYPE.TO, 'c_ob_type')
 
 # a pointer to PyObject
@@ -710,7 +717,7 @@
     argnames = callable.api_func.argnames
     argtypesw = zip(callable.api_func.argtypes,
                     [_name.startswith("w_") for _name in argnames])
-    error_value = callable.api_func.error_value
+    error_value = getattr(callable.api_func, "error_value", CANNOT_FAIL)
     if (isinstance(callable.api_func.restype, lltype.Ptr)
             and error_value is not CANNOT_FAIL):
         assert lltype.typeOf(error_value) == callable.api_func.restype
@@ -720,6 +727,7 @@
     signature = (tuple(argtypesw),
                  callable.api_func.restype,
                  callable.api_func.result_borrowed,
+                 callable.api_func.result_is_ll,
                  error_value,
                  gil)
 
@@ -769,7 +777,7 @@
         assert False
 
 def make_wrapper_second_level(space, callable2name, argtypesw, restype,
-                              result_borrowed, error_value, gil):
+                              result_borrowed, result_is_ll, error_value, gil):
     from rpython.rlib import rgil
     argtypes_enum_ui = unrolling_iterable(enumerate(argtypesw))
     fatal_value = restype._defl()
@@ -862,13 +870,17 @@
 
             elif is_PyObject(restype):
                 if is_pyobj(result):
-                    assert 0, "XXX retval = result"
+                    assert result_is_ll
                 else:
+                    assert not result_is_ll
                     if result_borrowed:
                         result = as_pyobj(space, result)
                     else:
                         result = make_ref(space, result)
-                    retval = rffi.cast(restype, result)
+                retval = rffi.cast(restype, result)
+
+            elif restype is not lltype.Void:
+                retval = rffi.cast(restype, result)
 
         except Exception, e:
             unexpected_exception(callable2name[callable], e, tb)
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
@@ -124,7 +124,7 @@
 
 #_______________________________________________________________________
 
-@cpython_api([CONST_STRING, Py_ssize_t], PyObject)
+@cpython_api([CONST_STRING, Py_ssize_t], PyObject, result_is_ll=True)
 def PyString_FromStringAndSize(space, char_p, length):
     if char_p:
         s = rffi.charpsize2str(char_p, length)
diff --git a/pypy/module/cpyext/frameobject.py 
b/pypy/module/cpyext/frameobject.py
--- a/pypy/module/cpyext/frameobject.py
+++ b/pypy/module/cpyext/frameobject.py
@@ -67,7 +67,8 @@
     track_reference(space, py_obj, w_obj)
     return w_obj
 
-@cpython_api([PyThreadState, PyCodeObject, PyObject, PyObject], PyFrameObject)
+@cpython_api([PyThreadState, PyCodeObject, PyObject, PyObject], PyFrameObject,
+             result_is_ll=True)
 def PyFrame_New(space, tstate, w_code, w_globals, w_locals):
     typedescr = get_typedescr(PyFrame.typedef)
     py_obj = typedescr.allocate(space, space.gettypeobject(PyFrame.typedef))
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
@@ -34,11 +34,11 @@
 def PyObject_Free(space, ptr):
     lltype.free(ptr, flavor='raw')
 
-@cpython_api([PyTypeObjectPtr], PyObject)
+@cpython_api([PyTypeObjectPtr], PyObject, result_is_ll=True)
 def _PyObject_New(space, type):
     return _PyObject_NewVar(space, type, 0)
 
-@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject)
+@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True)
 def _PyObject_NewVar(space, type, itemcount):
     w_type = from_ref(space, rffi.cast(PyObject, type))
     assert isinstance(w_type, W_TypeObject)
@@ -63,7 +63,7 @@
     if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
         Py_DecRef(space, rffi.cast(PyObject, pto))
 
-@cpython_api([PyTypeObjectPtr], PyObject)
+@cpython_api([PyTypeObjectPtr], PyObject, result_is_ll=True)
 def _PyObject_GC_New(space, type):
     return _PyObject_New(space, type)
 
@@ -193,7 +193,7 @@
     space.delitem(w_obj, w_key)
     return 0
 
-@cpython_api([PyObject, PyTypeObjectPtr], PyObject)
+@cpython_api([PyObject, PyTypeObjectPtr], PyObject, result_is_ll=True)
 def PyObject_Init(space, obj, type):
     """Initialize a newly-allocated object op with its type and initial
     reference.  Returns the initialized object.  If type indicates that the
@@ -207,7 +207,7 @@
     obj.c_ob_refcnt = 1
     return obj
 
-@cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject)
+@cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject, 
result_is_ll=True)
 def PyObject_InitVar(space, py_obj, type, size):
     """This does everything PyObject_Init() does, and also initializes the
     length information for a variable-size object."""
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -168,8 +168,16 @@
     state = space.fromcache(InterpreterState)
     return state.get_thread_state(space)
 
-@cpython_api([], PyObject, error=CANNOT_FAIL)
+@cpython_api([], PyObject, result_is_ll=True, error=CANNOT_FAIL)
 def PyThreadState_GetDict(space):
+    """Return a dictionary in which extensions can store thread-specific state
+    information.  Each extension should use a unique key to use to store state 
in
+    the dictionary.  It is okay to call this function when no current thread 
state
+    is available. If this function returns NULL, no exception has been raised 
and
+    the caller should assume no current thread state is available.
+
+    Previously this could only be called when a current thread is active, and 
NULL
+    meant that an exception was raised."""
     state = space.fromcache(InterpreterState)
     return state.get_thread_state(space).c_dict
 
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1156,19 +1156,6 @@
     PyInterpreterState_Clear()."""
     raise NotImplementedError
 
-@cpython_api([], PyObject)
-def PyThreadState_GetDict(space):
-    """Return a dictionary in which extensions can store thread-specific state
-    information.  Each extension should use a unique key to use to store state 
in
-    the dictionary.  It is okay to call this function when no current thread 
state
-    is available. If this function returns NULL, no exception has been raised 
and
-    the caller should assume no current thread state is available.
-
-    Previously this could only be called when a current thread is active, and 
NULL
-    meant that an exception was raised."""
-    borrow_from()
-    raise NotImplementedError
-
 @cpython_api([lltype.Signed, PyObject], rffi.INT_real, error=CANNOT_FAIL)
 def PyThreadState_SetAsyncExc(space, id, exc):
     """Asynchronously raise an exception in a thread. The id argument is the 
thread
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
@@ -127,7 +127,7 @@
 
 #_______________________________________________________________________
 
-@cpython_api([Py_ssize_t], PyObject)
+@cpython_api([Py_ssize_t], PyObject, result_is_ll=True)
 def PyTuple_New(space, size):
     return rffi.cast(PyObject, new_empty_tuple(space, size))
 
@@ -150,7 +150,8 @@
         decref(space, old_ref)
     return 0
 
-@cpython_api([PyObject, Py_ssize_t], PyObject, result_borrowed=True)
+@cpython_api([PyObject, Py_ssize_t], PyObject,
+             result_borrowed=True, result_is_ll=True)
 def PyTuple_GetItem(space, ref, index):
     if not tuple_check_ref(space, ref):
         PyErr_BadInternalCall(space)
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -752,7 +752,7 @@
     w_type2 = from_ref(space, rffi.cast(PyObject, b))
     return int(abstract_issubclass_w(space, w_type1, w_type2)) #XXX correct?
 
-@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject)
+@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True)
 def PyType_GenericAlloc(space, type, nitems):
     from pypy.module.cpyext.object import _PyObject_NewVar
     return _PyObject_NewVar(space, type, nitems)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to